JavaScript'te ayın son gününü hesapla


277

Eğer sağlarsanız 0olarak dayValueiçinde Date.setFullYearsize bir önceki ayın son günü olsun:

d = new Date(); d.setFullYear(2008, 11, 0); //  Sun Nov 30 2008

Mozilla'da bu davranışa atıfta bulunulmaktadır . Bu güvenilir bir çapraz tarayıcı özelliği mi yoksa alternatif yöntemlere mi bakmalıyım?


Belirttiğiniz ayın son günü demek istemiyor musunuz? Kasım ayında 30 gün ve Ekim ayında 31 gün vardır.
Chris Serra

16
Javascript'te aylar sıfır tabanlıdır, bu nedenle 11 Aralık
Greg

2
@TheCloudlessSky - konsolunuzda deneyin ... (2008,11,0) Aralık'ın sıfırıncı günü ve dolayısıyla Kasım'ın son günü
Ken

@Ken - Evet - "0" olduğunu fark etmedim :)) ... sabah çok erkenydi.
TheCloudlessSky

Yanıtlar:


425
var month = 0; // January
var d = new Date(2008, month + 1, 0);
alert(d); // last day in January

IE 6:                     Thu Jan 31 00:00:00 CST 2008
IE 7:                     Thu Jan 31 00:00:00 CST 2008
IE 8: Beta 2:             Thu Jan 31 00:00:00 CST 2008
Opera 8.54:               Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.27:               Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.60:               Thu Jan 31 2008 00:00:00 GMT-0600
Firefox 2.0.0.17:         Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Firefox 3.0.3:            Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Google Chrome 0.2.149.30: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Safari for Windows 3.1.2: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)

Çıktı farklılıkları toString(), tarihler farklı olduğu için değil uygulamadaki farklılıklardan kaynaklanmaktadır.

Tabii ki, yukarıda tanımlanan tarayıcıların 0'ı bir önceki ayın son günü olarak kullanması, yapmaya devam edecekleri anlamına gelmez veya listelenmeyen tarayıcıların bunu yapacağına inanır, ancak her tarayıcıda aynı şekilde.


19
Mükemmel çalışıyor. Meraktan, javascript'i tüm bu motorlarda çalıştırmak için ne kullanıyorsunuz? Her şey hazır mı, yoksa bir çeşit alet mi?
neonski

5
gerçek günü almak için d.getDate () kullanabilirsiniz.
Aralık'ta

35
"tarayıcıların… bir önceki ayın son günü olarak 0 kullanması, bunu yapmaya devam edecekleri anlamına gelmez". Evet, ECMA-262 ile yapmaları gerekiyor.
RobG

3
Lütfen kullanarak bu notu new Dateise o kadar çok daha yavaş diğer hesaplama yöntemlerine göre o bile perf grafikte görünmüyor : jsperf.com/days-in-month-perf-test/6
Kodlama Gone

4
Chrome 48.0.2564.116'da benim için çalışmıyor. Belki de bu yol 'standart' olmaktan çıkmıştır.
xarlymg89

77

Bir sonraki ayın ilk günü ile bir ara tarih kullanır ve bir önceki günün tarihini döndürürdüm:

int_d = new Date(2008, 11+1,1);
d = new Date(int_d - 1);

Göre ECMAScript şartname , "Tarih" yapıcı yararlanarak size işaret geçerli olduğu gibi. "MakeDay" işlevi tarafından belirtilen algoritmayı takiben, sorunu güzelce ele almalıdır.
Pablo Cabrera

1
Bu en iyi çözüm IMO'sudur. Kabul edilen cevabı denedim ancak mevcut ayın sonunu getirirken bazı hatalar var. Bugünün tarihini döndürür. Bunun neden olduğunu bilmiyorum.
Gogol

1
Hatayı üreyemiyorum. Bu bana tüm tarayıcılarda doğru tarihi verir:today = new Date(); new Date(today.getFullYear(), today.getMonth()+1, 0).toString();
orad

Bu, ayın son günü için, zamanın milisaniyeye ayarlanmış bir tarih nesnesi oluşturur (örn. 23: 59: 59.999). OP'de yöntemi kullanmak ve ekstra adımı ve Date nesnesini kaydetmek daha iyidir.
RobG

@RobG: Kabul ediyorum! benim çözümümün anlaşılması daha kolay olsa da, ayın son günü için 0 kullanma fikri bence biraz tıkalı geliyor.
karlipoppins

72

Bunun benim için en iyi çözüm olduğunu düşünüyorum. Date nesnesinin sizin için hesaplamasına izin verin.

var today = new Date();
var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0);

Day parametresini 0 olarak ayarlamak, bir önceki ayın son günü olan ayın ilk gününden bir gün daha az anlamına gelir.


1
Tamam, seçilen cevabın aynı önerdiğini fark ettim. Bu, en hızlı ve en güvenilir yoldur ve takvimin türünden bağımsız olarak çalışır. Örneğin, Tarih Gregoryen takvimi dışında bir şey uygularsa, yine de işe yarayacaktır. Tarih nesnesinin Gregoryen olmayan uygulamasının bir örneği için intldate.codeplex.com adresine bakın .
orad

1
@orad: Bu yöntem bazı alternatiflerden çok daha yavaş olduğu için bir şeyin "en hızlı" olduğunu iddia etmeye dikkat edin . Kullanımı new Dateise o kadar çok yavaş hatta perf grafikte görünmüyor : jsperf.com/days-in-month-perf-test/6
Kodlama Gone

@TrueBlueAussie Tamam. Daha hızlı olduğunu varsaymıştım çünkü yerli olduğu için. Ama haklısın, hızlı değil. Test ettiğiniz için teşekkürler. Her neyse, bu çözüm benim için en iyisi çünkü özlü ve okunabilir ve diğer tüm çözümlerin aksine Gregoryen takvimine bağlı değil.
orad

"diğer tüm çözümlerin aksine Gregoryen Takvimi bağlı değildir" !!! Bu algoritma 1-4000 yıllarında benimkiyle aynı değerleri döndürür. jsfiddle.net/2973x9m3/3 Bunun hangi ek tarih aralığını destekleyeceğini iddia ediyorsunuz (bu yararlı olabilir)? :)
Gone Coding

1
Yerel JS Tarihi yalnızca Gregoryen takvimini kullanır. Ancak diğer takvim türlerini almak için başka bir uygulama ile alay edebilirsiniz. Örneğin, bkz. IntlDate . Aylık görünümler oluşturmak için Date nesnelerini kullanan bir tarih seçiciniz varsa, aynı arabirime sahip oldukları sürece hangi Tarih uygulamasının (yerel veya alaycı) kullandığını önemsemez. Bu nedenle, paylaşılan bir arayüz kullanmak, her takvimde bir ayda kaç gün olduğunu bilmek zorunda kalmadan farklı Takvim türleri arasında geçiş yapmanıza olanak tanır.
orad

25

Bilgisayar terimleriyle new Date()ve regular expressionçözümler yavaş! Süper hızlı (ve süper şifreli) bir astar istiyorsanız, bunu deneyin ( formatta molduğu varsayılarak Jan=1). En iyi performansı elde etmek için farklı kod değişikliklerini denemeye devam ediyorum.

Şu anki en hızlı sürümüm:

Bu ilgili soruyu inceledikten sonra Bitsel operatörleri (inanılmaz hız) kullanarak yıl kontrolü yapın ve 25 ve 15 sihirli sayısının neyi temsil ettiğini keşfettikten sonra, bu optimize edilmiş cevaplar meleziyle karşılaştım:

function getDaysInMonth(m, y) {
    return m===2 ? y & 3 || !(y%25) && y & 15 ? 28 : 29 : 30 + (m+(m>>3)&1);
}

Bit değişimi göz önüne alındığında, bu açıkça m& yparametrelerinizin her ikisi de tamsayı olduğunu varsayar , çünkü sayıları dize olarak geçirmek garip sonuçlara neden olur.

JSFiddle: http://jsfiddle.net/TrueBlueAussie/H89X3/22/

JSPerf sonuçları: http://jsperf.com/days-in-month-head-to-head/5

Nedense, (m+(m>>3)&1)daha etkilidir (5546>>m&1)üzerinde neredeyse tüm tarayıcılar.

Hız için tek gerçek rekabet @GitaarLab'dan, bu yüzden test etmemiz için kafa kafaya bir JSPerf oluşturdum: http://jsperf.com/days-in-month-head-to-head/5


Bu benim artık yıl cevap dayalı çalışır: javascript artık yıl bulmak için bu cevap burada Bitwise operatörleri (şaşırtıcı hız) yanı sıra aşağıdaki ikili mantık kullanarak yıl kontrol edin .

İkili aylarda hızlı bir ders:

İstediğiniz ayların dizinini (Ocak = 1) ikili olarak yorumlarsanız , 31 günlük ayların ya bit 3 temiz ve 0 biti ayarlanmış ya da bit 3 set ve 0 biti temiz olduğunu fark edeceksiniz.

Jan = 1  = 0001 : 31 days
Feb = 2  = 0010
Mar = 3  = 0011 : 31 days
Apr = 4  = 0100
May = 5  = 0101 : 31 days
Jun = 6  = 0110
Jul = 7  = 0111 : 31 days
Aug = 8  = 1000 : 31 days
Sep = 9  = 1001
Oct = 10 = 1010 : 31 days
Nov = 11 = 1011
Dec = 12 = 1100 : 31 days

Araçlarla Yani değeri 3 ile yer kayabilir >> 3orjinali ile, XOR bit ^ mve sonuç olup olmadığını görmek 1veya 0 bit 0 konumunda kullanarak & 1. Not: Görünen o ki +XOR ( ^) ' dan biraz daha hızlıdır ve (m >> 3) + maynı sonucu bit 0'da verir.

JSPerf sonuçları : http://jsperf.com/days-in-month-perf-test/6



1
@GitaarLAB: Zaten bir sözün var ve bu asla seninkiyle tam olarak aynı değildi, bildiğin gibi. Diğer algoritmaların artımlı güncellenmesi "orijinal algo" ile aynı değildir. Ben de bu cevaba çok çaba
Gone Coding

@TrueBlueAussie: Gelecekteki okuyucuları sadece daha fazla bilgi hazinemize yönlendirmek istedim (her ikimiz de cevaplarımızı bağladım, böylece başka bir şey almak isteyen veya gitmek isteyen herkes ne zaman ve neden yaptığımızı görmek için düzenleme tarihimize bakabilir ). Hala tam bir rekabet gününü hatırlıyorum! :)Gönderdiğim ilk cevap sürümünde, gerçekten bir karakterin tıraş olabileceği ve bununla sonuçlanabileceğimiz, kaldırılmamış gereksiz bir parantez seti vardı. O eğlenceli gün için hala minnettarım, şerefe!
GitaarLAB

1
Söz Lütfen yve mdeğişkenler dize değil tamsayı olmak zorunda! Örneğin Şubat için 30 gibi yanlış hesaplamalar yapar. Çalıştırmak için parseInt()işlev kullanmak zorunda kaldı .
bunun yerine


16

Lebreeze tarafından sağlanan çözeltide küçük bir değişiklik :

function daysInMonth(iMonth, iYear)
{
    return new Date(iYear, iMonth, 0).getDate();
}

Bu return new Date(iYear, 1 + iMonth, 0).getDate();@ lebreeze'nin çözümüne eşdeğer olmalıdır .
Moos

6

Son zamanlarda benzer bir şey yapmak zorunda kaldım, bu benim geldi:

/**
* Returns a date set to the begining of the month
* 
* @param {Date} myDate 
* @returns {Date}
*/
function beginningOfMonth(myDate){    
  let date = new Date(myDate);
  date.setDate(1)
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);   
  return date;     
}

/**
 * Returns a date set to the end of the month
 * 
 * @param {Date} myDate 
 * @returns {Date}
 */
function endOfMonth(myDate){
  let date = new Date(myDate);
  date.setMonth(date.getMonth() +1)
  date.setDate(0);
  date.setHours(23);
  date.setMinutes(59);
  date.setSeconds(59);
  return date;
}

Bir tarihte ilettiğinizde ayın başına veya ayın sonuna ayarlanmış bir tarih döndürülür.

begninngOfMonthFonksiyon oldukça kendini açıklayıcı olmakla birlikte, ne de oluyor endOfMonthişlevi kullanıyorum sonra bir sonraki aya ay bir arttırılarak ve olmam setDate(0)bir parçasıdır önceki ayın son günden güne geri almak için setDate spec:

https://developer.mozilla.org/tr-TR/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate https://www.w3schools.com/jsref/jsref_setdate.asp

Daha sonra saat / dakika / saniyeyi günün sonuna ayarlıyorum, böylece bir tarih aralığı bekleyen bir çeşit API kullanıyorsanız, o günün tamamını yakalayabileceksiniz. Bu bölüm, orijinal gönderinin istediklerinin ötesine geçebilir, ancak benzer bir çözüm arayan başka birine yardımcı olabilir.

Düzenleme: Ayrıca ekstra mil gitmek ve setMilliseconds()ekstra kesin olmak istiyorsanız ile milisaniye ayarlayabilirsiniz .


4

bunu dene.

lastDateofTheMonth = new Date(year, month, 0)

misal:

new Date(2012, 8, 0)

çıktı:

Date {Fri Aug 31 2012 00:00:00 GMT+0900 (Tokyo Standard Time)}

5
Yine de, ayların sıfır temelli olduğunu unutmayın, bu nedenle ayın Eylül değil, gerçekten Eylül olduğu için "8" değerini geçer.
Steve J

3

Bu benim için çalışıyor. Verilen yılın ve ayın son gününü sağlayacaktır:

var d = new Date(2012,02,0);
var n = d.getDate();
alert(n);

1
"2" nin önündeki 0 ile dikkat edin, sekizli olarak yorumlanacaktır.
Walfrat

1

Bu güzel çalışıyor:

Date.prototype.setToLastDateInMonth = function () {

    this.setDate(1);
    this.setMonth(this.getMonth() + 1);
    this.setDate(this.getDate() - 1);

    return this;
}

1

Bu size mevcut ayı ilk ve son günü verecektir.

'Yılı' değiştirmeniz gerekiyorsa d.getFullYear () öğesini kaldırın ve yılınızı ayarlayın.

'Ay'ı değiştirmeniz gerekiyorsa, d.getMonth () öğesini kaldırın ve yılınızı ayarlayın.

var d = new Date();
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var fistDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth(), 1).getDay())];
	var LastDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth() + 1, 0).getDay())]; 
console.log("First Day :" + fistDayOfMonth); 
console.log("Last Day:" + LastDayOfMonth);
alert("First Day :" + fistDayOfMonth); 
alert("Last Day:" + LastDayOfMonth);


1

Bunu dene:

function _getEndOfMonth(time_stamp) {
    let time = new Date(time_stamp * 1000);
    let month = time.getMonth() + 1;
    let year = time.getFullYear();
    let day = time.getDate();
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            day = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            day = 30;
            break;
        case 2:
            if (_leapyear(year))
                day = 29;
            else
                day = 28;
            break
    }
    let m = moment(`${year}-${month}-${day}`, 'YYYY-MM-DD')
    return m.unix() + constants.DAY - 1;
}

function _leapyear(year) {
    return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
}

1

Aşağıdaki fonksiyon ayın son gününü verir:

function getLstDayOfMonFnc(date) {
  return new Date(date.getFullYear(), date.getMonth(), 0).getDate()
}

console.log(getLstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 29
console.log(getLstDayOfMonFnc(new Date(2017, 2, 15))) // Output : 28
console.log(getLstDayOfMonFnc(new Date(2017, 11, 15))) // Output : 30
console.log(getLstDayOfMonFnc(new Date(2017, 12, 15))) // Output : 31

Benzer şekilde ayın ilk gününü de alabiliriz:

function getFstDayOfMonFnc(date) {
  return new Date(date.getFullYear(), date.getMonth(), 1).getDate()
}

console.log(getFstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 1


0
function getLastDay(y, m) {
   return 30 + (m <= 7 ? ((m % 2) ? 1 : 0) : (!(m % 2) ? 1 : 0)) - (m == 2) - (m == 2 && y % 4 != 0 || !(y % 100 == 0 && y % 400 == 0)); 
}

0
const today = new Date();

let beginDate = new Date();

let endDate = new Date();

// fist date of montg

beginDate = new Date(

  `${today.getFullYear()}-${today.getMonth() + 1}-01 00:00:00`

);

// end date of month 

// set next Month first Date

endDate = new Date(

  `${today.getFullYear()}-${today.getMonth() + 2}-01 :23:59:59`

);

// deducting 1 day

endDate.setDate(0);

0

Tarihi ayarlamanız ve ardından günü sıfıra ayarlamanız gerekir, böylece ay tarih işlevinde 1 - 31'de başlar ve son günü elde eder ^^

var last = new Date(new Date(new Date().setMonth(7)).setDate(0)).getDate();
console.log(last);


0

İşte GMT'yi ve ilk tarihin zamanını koruyan bir cevap

var date = new Date();

var first_date = new Date(date); //Make a copy of the date we want the first and last days from
first_date.setUTCDate(1); //Set the day as the first of the month

var last_date = new Date(first_date); //Make a copy of the calculated first day
last_date.setUTCMonth(last_date.getUTCMonth() + 1); //Add a month
last_date.setUTCDate(0); //Set the date to 0, this goes to the last day of the previous month

console.log(first_date.toJSON().substring(0, 10), last_date.toJSON().substring(0, 10)); //Log the dates with the format yyyy-mm-dd


0

Bunun sadece bir anlambilim meselesi olduğunu biliyorum, ama sonunda bu formda kullandım.

var lastDay = new Date(new Date(2008, 11+1,1) - 1).getDate();
console.log(lastDay);

Fonksiyonlar iç argümandan dışa doğru çözüldüğünden, aynı şekilde çalışır.

Daha sonra, yıl ve ay / yılı geçerli tarihte olsun, gerekli ayrıntılarla değiştirebilirsiniz. Veya belirli bir ay / yıl.


0

Milisaniye cinsinden ayın tam sonuna ihtiyacınız varsa (örneğin, bir zaman damgasında):

d = new Date()
console.log(d.toString())
d.setDate(1)
d.setHours(23, 59, 59, 999)
d.setMonth(d.getMonth() + 1)
d.setDate(d.getDate() - 1)
console.log(d.toString())

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.