Soru JavaScript'teki iki tarih arasındaki Ay farkı


JavaScript'teki iki Date () nesnesinin farkını nasıl değiştirebilirim, ancak farkın yalnızca ay sayısını döndürürüm?

Herhangi bir yardım harika olurdu :)


93
2018-03-29 07:34


Menşei


Bir ay çok doğru bir ölçüm birimi değildir çünkü ayın hangi ay olduğuna bağlı olarak değişir. Bir aralık Ocak ve Şubat ayları arasında 30 gün sürüyorsa, bu, 31 günlük bir ay olarak düşünürseniz 1 aydan daha az, ancak 28 veya 29 gününü dikkate alırsanız 1 aydan daha uzun bir süre kalır. - Mark Byers
Çok iyi tanımlanmış bir soru değil. 28 Şubat 23:58 ile 1 Mart 00:01 bir ay mı? Ya da sadece bir gün? Ya da sadece üç dakika? Ya da üçü de? - Thilo
@Thilo Bunu uygulamak için ihtiyaç duyan birinin, yöneticilerinin ilk başta ne istediklerini bilmediği için cevapları olmayacaktır. :) - Dropped.on.Caprica


Cevaplar:


"Fark içindeki ay sayısı" nın tanımı, çok fazla yoruma tabidir. :-)

Bir JavaScript tarih nesnesinden yıl, ay ve ay alabilirsiniz. Aradığınız bilgiyi bağlı olarak, zaman içinde iki nokta arasında kaç ay olduğunu bulmak için bunları kullanabilirsiniz.

Örneğin, kapalı manşet, bu kaç tane olduğunu öğrenir tam aylar İki tarih arasında, kısmi ayları saymamak (örneğin, her bir tarihin bulunduğu ay hariç):

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth();
    return months <= 0 ? 0 : months;
}

monthDiff(
    new Date(2008, 10, 4), // November 4th, 2008
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 15: December 2008, all of 2009, and Jan & Feb 2010

monthDiff(
    new Date(2010, 0, 1),  // January 1st, 2010
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 1: February 2010 is the only full month between them

monthDiff(
    new Date(2010, 1, 1),  // February 1st, 2010
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 0: There are no *full* months between them

(JavaScript'teki ay değerlerinin 0 = Ocak ile başladığını unutmayın.)

Yukarıdaki fraksiyonel aylar dahil olmak çok daha karmaşıktır, çünkü tipik bir Şubat'taki üç gün, bu ayın (~% 10.714) Ağustos ayındaki üç gününden (~% 9.677) daha büyük bir kısmıdır ve elbette Şubat ayı hareketli bir hedeftir. bir sıçrama yılı olup olmamasına bağlı olarak.

Bazıları da var tarih ve zaman kütüphaneleri Bu tür şeyleri daha kolay hale getiren JavaScript için kullanılabilir.


176
2018-03-29 07:49



@ T.J .: İşleviniz için +1, OP'nin başlayabileceği yerlerin iyi bir örneğidir, ama en azından bir "tam" ayın (örneğin) 1 Şubat - 31 Mart arasında sayılması gerektiğini düşünürdüm :-) - Andy E
[geek_mode] Gregoryen şey üzerinde genişleyen: JavaScript sadece bir ekstrapole Gregoryen takvim ve sıçrama saniye yok sayar. Bu, diğer şeylerin yanı sıra, 15 Ekim 1582'den önceki herhangi bir tarihin yıl, ay veya gün sorgulandığında (örneğin bir dizeye dönüştürüldüğü zaman) yanlış bir şekilde düzeltileceği anlamına gelir, çünkü JavaScript Ayarlamayı yapmaz. (15 Ekim 1582'den önceki gün 4 Ekim 1582 idi; o yıldan 5’e 14’e çıkmadı.) [/ geek_mode] - T.J. Crowder
monthDiff (yeni Tarih (), yeni Tarih ()) -1 gerçekten beni şaşırtıyor :-( - Petr
"Month - = d1.getMonth () + 1; içindeki +1" i değil misiniz? gerekli? Bu +1 ile 2013-01-17 ve 2013-02-16 arasındaki fark 0'dır. - Briganti
+ 1'i kaldırmak zorunda kaldım months -= d1.getMonth() + 1; Doğru bir başlangıç ​​noktası için 2 tarih arasındaki ay sayısını doğru olarak bulmak için çok teşekkür ederiz! - bryan


return DisplayTo.getMonth() - DisplayFrom.getMonth()
       + (12 * (DisplayTo.getFullYear() - DisplayFrom.getFullYear()));

51
2017-11-30 10:59



Bu şimdiye kadar gördüğüm kodu anlamak için en kısa ve en kolay! - Omar
Her ayın başlaması haricinde bununla karmaşık bir şey yok. 31.03.2011 -> 01.05.2011 01.03.2011 -> 31.05.2011 tarihi itibariyle iki ay olacak, ancak kesin olmak için üç tane olmalı. - Natim
Bu cevap daha eksiksiz: stackoverflow.com/a/15158873/186202 - Natim
Sadece ay sayısını bilmek istiyorsanız bu bir harika !!!!! Aydaki günlere göre bilmeniz gerekiyorsa, bu işe yaramayacaktır. - OSDM
2018/01 ve 2017/01'in 12 ay arayla başlamasından başlayınız. Oradan geriye doğru çalışın. Bu cevap alır. ;) - Gerard ONeill


Bazen, sadece iki gün arasındaki ayın miktarını, gün bölümünü tamamen görmezden gelmek isteyebilirsiniz. Örneğin, iki tarihiniz varsa - 2013/06/21 ve 2013/10 / 18- ve sadece 2013/06 ve 2013/10 bölümlerini önemsediyseniz, senaryolar ve olası çözümler şunlardır:

var date1=new Date(2013,5,21);//Remember, months are 0 based in JS
var date2=new Date(2013,9,18);
var year1=date1.getFullYear();
var year2=date2.getFullYear();
var month1=date1.getMonth();
var month2=date2.getMonth();
if(month1===0){ //Have to take into account
  month1++;
  month2++;
}
var numberOfMonths; 

1.İki ay ve ay2 hariç iki tarih arasındaki ayların sayısını istiyorsanız

numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;

2. Aylardan birini dahil etmek istiyorsanız

numberOfMonths = (year2 - year1) * 12 + (month2 - month1);

3. Her iki ayı da dahil etmek istiyorsanız

numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;

25
2018-03-01 13:25



Güzel! Benim için mükemmel çalıştı.
Sonuncusu için tavsiye edeceğim: numberOfMonths=(year2-year1)*12+(month2-month1)+1; aynısını yapar ama benim için daha semantik olarak doğrudur - Natim
Evet, güzel ve zarif bir yaklaşım. - Mikayil Abdullayev
Bu en iyi cevaptı. Teşekkürler! - marienke
Bu basit ve temiz. Harika kod yazdığınız için teşekkürler. - zeros-and-ones


Ay, 28, 29, 30 veya 31 gün olmasına bakılmaksızın, tam ayları saymanız gerekiyorsa. Aşağıda çalışması gerekir.

var months = to.getMonth() - from.getMonth() 
    + (12 * (to.getFullYear() - from.getFullYear()));

if(to.getDate() < from.getDate()){
    months--;
}
return months;

Bu cevabın genişletilmiş bir versiyonu https://stackoverflow.com/a/4312956/1987208 ancak, 31 Ocak ile 1 Şubat (1 günlük) tarihleri ​​arasındaki dava için 1 ay hesapladığı durumu düzeltir.

Bu aşağıdakileri kapsayacaktır;

  • 1 Ocak-31 Ocak arası -> 30 gün ---> 0 (tam ay olmadığından mantıklı) sonuçlanır
  • 1 Şubat - 1 Mart ---> 28 veya 29 gün ---> 1 sonuçlanır (tam ay olduğundan beri mantıklı)
  • 15 Şubat - 15 Mar ---> 28 veya 29 gün ---> 1 sonuç (1 ay geçtikten sonra mantıklı)
  • 31 Ocak - 1 Şubat -> 1 gün ---> 0 ile sonuçlanacaktır (açık ancak belirtilen cevap 1 ay içinde sonuçlanır)

21
2018-01-09 13:02



Tha, buraya doğrulamak için geldiğimi düşündüm ve bu bana mantıklı gelen tek cevap. - Andreas
Bu, ayın daha kısa olduğu iki ayı karşılaştırırken işe yaramıyor. Örneğin, 31 Mart'tan 30 Nisan'a kadar. budur herşey nisan, bu yüzden cevap "1" olmalıdır. - Michael Blackburn


İşte, 2 tarih arasındaki ay sayısını doğru olarak veren bir işlev.
Varsayılan davranış yalnızca tüm ayları sayar, örn. 3 ay ve 1 gün 3 ay fark yaratacaktır. Bunu ayarlayarak bunu önleyebilirsiniz. roundUpFractionalMonths param trueBöylece 3 ay ve 1 günlük fark 4 ay olarak iade edilecektir.

Yukarıda kabul edilen cevap (T.J. Crowder'ın cevabı) doğru değil, bazen yanlış değerler döndürüyor.

Örneğin, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015')) döner 0 Bu açıkça yanlıştır. Doğru fark 1 ay veya 2 ay yuvarlanır.

İşte yazdığım işlev:

function getMonthsBetween(date1,date2,roundUpFractionalMonths)
{
    //Months will be calculated between start and end dates.
    //Make sure start date is less than end date.
    //But remember if the difference should be negative.
    var startDate=date1;
    var endDate=date2;
    var inverse=false;
    if(date1>date2)
    {
        startDate=date2;
        endDate=date1;
        inverse=true;
    }

    //Calculate the differences between the start and end dates
    var yearsDifference=endDate.getFullYear()-startDate.getFullYear();
    var monthsDifference=endDate.getMonth()-startDate.getMonth();
    var daysDifference=endDate.getDate()-startDate.getDate();

    var monthCorrection=0;
    //If roundUpFractionalMonths is true, check if an extra month needs to be added from rounding up.
    //The difference is done by ceiling (round up), e.g. 3 months and 1 day will be 4 months.
    if(roundUpFractionalMonths===true && daysDifference>0)
    {
        monthCorrection=1;
    }
    //If the day difference between the 2 months is negative, the last month is not a whole month.
    else if(roundUpFractionalMonths!==true && daysDifference<0)
    {
        monthCorrection=-1;
    }

    return (inverse?-1:1)*(yearsDifference*12+monthsDifference+monthCorrection);
};

19
2017-11-14 13:22



Cidden olsa, bunu kim reddetti? Haklı, kabul edilen cevap sadece ... yanlış. - Michael Blackburn
Bu en uygun cevaptır. - Kalyan Chavali
Tarih 1 22 Ocak ve tarih2 22 Ağustos olduğunu söylerseniz bu doğru değil. Öyleyse 7 döndürür, ki bu 8 olmalı? - Nicolai Harbo


JavaScript'te iki tarih arasındaki Aylarda Fark:

 start_date = new Date(year, month, day); //Create start date object by passing appropiate argument
 end_date = new Date(new Date(year, month, day)

başlangıç_tarihi ile bitiş_tarihi arasındaki toplam ay sayısı:

 total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())

7
2018-03-15 13:41



Lütfen kopyala yapıştır kodunu kullanın: jsfiddle.net/b1prajwm - YumYumYum


Bunun gerçekten geç olduğunu biliyorum, ancak başkalarına yardım etmesi durumunda onu yine de gönderiyorum. İşte, ortaya çıktığım bir fonksiyon, iki tarih arasındaki aylarda farklılıkları saymak için iyi bir iş gibi görünüyor. Kuşkusuz, BayCrowder'dan çok daha büyük bir tokluktur, ama tarih nesnesine adım atmak suretiyle daha doğru sonuçlar verir. AS3'te ama güçlü yazmayı bırakmanız ve JS'niz olacak. Dışarıda herkese daha iyi bakmanın tadını çıkarmaktan çekinmeyin!

    function countMonths ( startDate:Date, endDate:Date ):int
    {
        var stepDate:Date = new Date;
        stepDate.time = startDate.time;
        var monthCount:int;

        while( stepDate.time <= endDate.time ) { 
            stepDate.month += 1;
            monthCount += 1;
        }           

        if ( stepDate != endDate ) { 
            monthCount -= 1;
        }

        return monthCount;
    }

5
2017-07-21 21:28



Geçerli javascript gönderilmesi iyi bir başlangıç ​​olur. - RobG
Bu büyük olasılıkla doğru çoğu durum için yaklaşım. Takvimimizde çok fazla istisna ve vagary var, en iyi yaklaşım onları Date () gibi iyi test edilmiş bir kütüphaneye götürmektir. Çoğu (kısa) yayılım için, bu, hesaplanan yaklaşımlarla aynı cevabı döndürecektir, ancak uzun zaman aralıklarıyla uğraşırken (artık yıllar, artık yıllar değil, sıçrayan yıllar, sıçrama) saniyeler, vb.) aylar çıkarmanın ve yıllar eklendiğinde bir istisna haline gelme olasılığınız daha yüksek olur. Hesaplamanın en iyi olacağı istisnalar için cevabımı görün. - Michael Blackburn


Her tarihi ay cinsinden düşünün, sonra farkı bulmak için çıkartın.

var past_date = new Date('11/1/2014');
var current_date = new Date();

var difference = (current_date.getFullYear()*12 + current_date.getMonth()) - (past_date.getFullYear()*12 + past_date.getMonth());

Bu, iki tarih arasındaki ayların farkını alacak ve günleri görmezden gelecektir.


5
2017-11-22 06:17





@ T.J.'nin yanıtını genişletmek için, tam takvim ayları yerine basit aylar arıyorsanız, d2'nin tarihinin d1'den büyük veya eşit olduğunu kontrol edebilirsiniz. Yani d2, ayın d1'inde aydan daha fazlaysa 1 ay daha var demektir. Yani sadece bunu yapabilmeniz gerekir:

function monthDiff(d1, d2) {
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth();
    // edit: increment months if d2 comes later in its month than d1 in its month
    if (d2.getDate() >= d1.getDate())
        months++
    // end edit
    return months <= 0 ? 0 : months;
}

monthDiff(
    new Date(2008, 10, 4), // November 4th, 2008
    new Date(2010, 2, 12)  // March 12th, 2010
);
// Result: 16; 4 Nov – 4 Dec '08, 4 Dec '08 – 4 Dec '09, 4 Dec '09 – 4 March '10

Bu, tüm zaman sorunlarını (ör. 3 Mart saat 16:00 ve 3 Nisan saat 15:00) açıklamamaktadır, ancak daha doğru ve yalnızca birkaç satır kod için geçerlidir.


4
2018-03-18 21:33