Różnica miesięcy między dwoma datami w JavaScript
Jak obliczyć różnicę dla dwóch obiektów date () w JavaScript, zwracając tylko liczbę miesięcy różnicy?
Każda pomoc byłaby świetna:)
21 answers
Definicja "liczby miesięcy w różnicy" jest przedmiotem wielu interpretacji. :-)
Możesz pobrać Rok, Miesiąc i dzień miesiąca z obiektu JavaScript date. W zależności od tego, jakich informacji szukasz, możesz ich użyć, aby dowiedzieć się, ile miesięcy dzieli dwa punkty w czasie.
Na przykład, off-the-cuff, to dowiaduje się, ile pełne miesiące leżą między dwiema datami, nie licząc częściowych miesięcy (np. z wyłączeniem miesiąca każdego Data jest w):
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
(zauważ, że wartości miesiąca w JavaScript zaczynają się od 0 = styczeń.)
Włączenie miesięcy ułamkowych do powyższego jest znacznie bardziej skomplikowane, ponieważ trzy dni w typowym lutym to większy ułamek tego miesiąca (~10,714%) niż trzy dni w sierpniu (~9,677%), a oczywiście nawet Luty jest ruchomym celem w zależności od tego, czy jest to rok przestępny.
Istnieje również kilka bibliotek daty i czasu dostępnych dla JavaScript, które prawdopodobnie sprawiają, że łatwiej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-18 15:15:20
return DisplayTo.getMonth() - DisplayFrom.getMonth()
+ (12 * (DisplayTo.getFullYear() - DisplayFrom.getFullYear()));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-05 16:39:21
Czasami możesz chcieć uzyskać tylko ilość miesięcy między dwiema datami całkowicie ignorując część dnia. Na przykład, jeśli miałeś dwie daty - 2013/06/21 i 2013/10/18-i zależało Ci tylko na częściach 2013/06 i 2013/10, oto scenariusze i możliwe rozwiązania: {]}
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.Jeśli chcesz tylko liczbę miesięcy między dwoma datami z wyłączeniem month1 i month2
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;
2.Jeśli chcesz dołączyć jeden z miesięcy
numberOfMonths = (year2 - year1) * 12 + (month2 - month1);
3.Jeśli chcesz dołączyć oba miesiące
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-11 11:59:45
Jeśli musisz policzyć pełne miesiące, niezależnie od tego, czy miesiąc jest 28, 29, 30 czy 31 dni. Poniżej powinno działać.
var months = to.getMonth() - from.getMonth()
+ (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
months--;
}
return months;
To jest rozszerzona wersja odpowiedzi https://stackoverflow.com/a/4312956/1987208 ale rozwiązuje przypadek, w którym oblicza 1 miesiąc dla przypadku od 31 stycznia do 1 lutego(1 dzień).
To będzie obejmować następujące;
- od 1 stycznia do 31 stycznia - - - > 30 dni - - - > spowoduje 0 (logiczne, ponieważ nie jest pełne miesiąc)
- od 1 lutego do 1 marca - - - > 28 lub 29 dni - - - > spowoduje 1 (logiczne, ponieważ jest to pełny miesiąc)
- od 15 lutego do 15 marca - - - > 28 lub 29 dni - - - > spowoduje 1 (logiczny od miesiąca minął)
- 31st Jan to 1st Feb - - - > 1 day - - - > will result in 0 (oczywista ale wspomniana odpowiedź w poście daje za 1 miesiąc)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:09
Oto funkcja, która dokładnie podaje liczbę miesięcy między 2 datami.
Domyślne zachowanie liczy tylko całe miesiące, np. 3 miesiące i 1 dzień spowoduje różnicę 3 miesięcy. Możesz temu zapobiec, ustawiając {[1] } param jako true
, więc różnica 3 miesięcy i 1 dni zostanie zwrócona jako 4 miesiące.
Zaakceptowana odpowiedź powyżej (odpowiedź T. J. Crowdera) nie jest dokładna, czasami zwraca błędne wartości.
Na przykład, monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))
zwraca 0
co jest oczywiście złe. Prawidłowa różnica to jeden cały miesiąc lub dwa miesiące zaokrąglone w górę.
Oto funkcja, którą napisałem:
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);
};
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-30 22:08:46
Różnica miesięcy między dwiema datami w JavaScript:
start_date = new Date(year, month, day); //Create start date object by passing appropiate argument
end_date = new Date(new Date(year, month, day)
Suma miesięcy między datą początkową i datą końcową:
total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())
Wiem, że jest bardzo późno, ale publikowanie go i tak na wypadek, gdyby pomogło innym. Oto funkcja wymyśliłem, że wydaje się zrobić dobrą robotę liczenia różnic w miesiącach między dwoma datami. Jest to wprawdzie o wiele bardziej raunchier niż pana Crowdera, ale zapewnia dokładniejsze wyniki, przechodząc przez obiekt daty. Jest w AS3, ale powinieneś po prostu być w stanie rzucić silne typowanie i będziesz miał JS. Nie krępuj się, aby było ładniej wygląda ktoś tam!
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;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-21 21:28:35
Rozważmy każdą datę w kategoriach miesięcy, a następnie odejmij, aby znaleźć różnicę.
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());
To da Ci różnicę miesięcy między dwiema datami, ignorując dni.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-22 06:17:32
Aby rozwinąć odpowiedź @T. J., jeśli szukasz prostych miesięcy, a nie pełnych miesięcy kalendarzowych, możesz po prostu sprawdzić, czy data d2 jest większa lub równa niż d1. to znaczy, jeśli d2 jest później w swoim miesiącu niż d1 jest w swoim miesiącu, to jest jeszcze 1 miesiąc. Więc powinieneś być w stanie po prostu to zrobić:
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
Nie uwzględnia to całkowicie problemów czasowych (np. 3 marca o 16:00 i 3 kwietnia o 15: 00), ale jest bardziej dokładny i dotyczy tylko kilku linijek kodu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-20 21:39:44
Istnieją dwa podejścia, matematyczne i szybkie, ale podlegające kaprysom w kalendarzu, lub iteracyjne i powolne, ale obsługujące wszystkie dziwactwa (lub przynajmniej deleguje obsługę ich do dobrze przetestowanej biblioteki).
Jeśli iterujesz kalendarz, zwiększając datę rozpoczęcia o jeden miesiąc i sprawdzając, czy mijamy datę końcową. To deleguje obsługę anomalii do wbudowanych klas date (), ale może być powolne , Jeśli robisz to przez dużą liczbę dat. James ' answer takes takie podejście. Chociaż nie podoba mi się ten pomysł, myślę, że jest to "najbezpieczniejsze" podejście, a jeśli robisz tylko jedną kalkulację, różnica wydajności naprawdę jest znikoma. Staramy się nadmiernie optymalizować zadania, które będą wykonywane tylko raz.
Teraz, jeśli obliczasz tę funkcję na zbiorze danych, prawdopodobnie nie chcesz uruchamiać tej funkcji w każdym wierszu(lub broń Boże, wiele razy na rekord). W takim przypadku możesz użyć prawie każdej z pozostałych odpowiedzi tutaj z wyjątkiem akceptowana odpowiedź, która jest po prostu zła (różnica między new Date()
i new Date()
wynosi -1)?
function diffInMonths(from, to){
var months = to.getMonth() - from.getMonth() + (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
var newFrom = new Date(to.getFullYear(),to.getMonth(),from.getDate());
if (to < newFrom && to.getMonth() == newFrom.getMonth() && to.getYear() %4 != 0){
months--;
}
}
return months;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-16 15:27:13
Tutaj idziesz inne podejście z mniejszym zapętleniem:
calculateTotalMonthsDifference = function(firstDate, secondDate) {
var fm = firstDate.getMonth();
var fy = firstDate.getFullYear();
var sm = secondDate.getMonth();
var sy = secondDate.getFullYear();
var months = Math.abs(((fy - sy) * 12) + fm - sm);
var firstBefore = firstDate > secondDate;
firstDate.setFullYear(sy);
firstDate.setMonth(sm);
firstBefore ? firstDate < secondDate ? months-- : "" : secondDate < firstDate ? months-- : "";
return months;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-23 23:21:35
To powinno działać dobrze:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months += d2.getMonth() - d1.getMonth();
return months;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-06 22:06:26
function calcualteMonthYr(){
var fromDate =new Date($('#txtDurationFrom2').val()); //date picker (text fields)
var toDate = new Date($('#txtDurationTo2').val());
var months=0;
months = (toDate.getFullYear() - fromDate.getFullYear()) * 12;
months -= fromDate.getMonth();
months += toDate.getMonth();
if (toDate.getDate() < fromDate.getDate()){
months--;
}
$('#txtTimePeriod2').val(months);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-29 06:07:14
Oblicz różnicę między dwoma datami obejmują ułamek miesiąca (dni).
var difference = (date2.getDate() - date1.getDate()) / 30 +
date2.getMonth() - date1.getMonth() +
(12 * (date2.getFullYear() - date1.getFullYear()));
Na przykład:
Data 1: 24/09/2015 (24 września 2015)
Data 2: 09/11/2015 (9th Nov 2015)
różnica: 2,5 (miesiące)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-03 16:44:59
Następujący kod zwraca pełne miesiące między dwoma datami, biorąc pod uwagę również nr dni częściowych miesięcy.
var monthDiff = function(d1, d2) {
if( d2 < d1 ) {
var dTmp = d2;
d2 = d1;
d1 = dTmp;
}
var months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
if( d1.getDate() <= d2.getDate() ) months += 1;
return months;
}
monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 20))
> 1
monthDiff(new Date(2015, 01, 20), new Date(2015, 02, 19))
> 0
monthDiff(new Date(2015, 01, 20), new Date(2015, 01, 22))
> 0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-25 22:07:57
function monthDiff(d1, d2) {
var months, d1day, d2day, d1new, d2new, diffdate,d2month,d2year,d1maxday,d2maxday;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months -= d1.getMonth() + 1;
months += d2.getMonth();
months = (months <= 0 ? 0 : months);
d1day = d1.getDate();
d2day = d2.getDate();
if(d1day > d2day)
{
d2month = d2.getMonth();
d2year = d2.getFullYear();
d1new = new Date(d2year, d2month-1, d1day,0,0,0,0);
var timeDiff = Math.abs(d2.getTime() - d1new.getTime());
diffdate = Math.abs(Math.ceil(timeDiff / (1000 * 3600 * 24)));
d1new = new Date(d2year, d2month, 1,0,0,0,0);
d1new.setDate(d1new.getDate()-1);
d1maxday = d1new.getDate();
months += diffdate / d1maxday;
}
else
{
if(!(d1.getMonth() == d2.getMonth() && d1.getFullYear() == d2.getFullYear()))
{
months += 1;
}
diffdate = d2day - d1day + 1;
d2month = d2.getMonth();
d2year = d2.getFullYear();
d2new = new Date(d2year, d2month + 1, 1, 0, 0, 0, 0);
d2new.setDate(d2new.getDate()-1);
d2maxday = d2new.getDate();
months += diffdate / d2maxday;
}
return months;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-16 13:17:44
Poniżej logika pobierze różnicę w miesiącach
(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-16 00:10:22
AnyVar = (((DisplayTo.getFullYear () * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear () * 12) + DisplayFrom.getMonth ()));
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-11 06:03:12
Zobacz czego używam:
function monthDiff() {
var startdate = Date.parseExact($("#startingDate").val(), "dd/MM/yyyy");
var enddate = Date.parseExact($("#endingDate").val(), "dd/MM/yyyy");
var months = 0;
while (startdate < enddate) {
if (startdate.getMonth() === 1 && startdate.getDate() === 28) {
months++;
startdate.addMonths(1);
startdate.addDays(2);
} else {
months++;
startdate.addMonths(1);
}
}
return months;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-07 12:31:11
Liczy również dni i konwertuje je w miesiącach.
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12; //calculates months between two years
months -= d1.getMonth() + 1;
months += d2.getMonth(); //calculates number of complete months between two months
day1 = 30-d1.getDate();
day2 = day1 + d2.getDate();
months += parseInt(day2/30); //calculates no of complete months lie between two dates
return months <= 0 ? 0 : months;
}
monthDiff(
new Date(2017, 8, 8), // Aug 8th, 2017 (d1)
new Date(2017, 12, 12) // Dec 12th, 2017 (d2)
);
//return value will be 4 months
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-11 11:12:37
Jednym z rozwiązań byłoby napisanie prostej usługi Java Web Service (REST/JSON) wykorzystującej bibliotekę JODA
Http://joda-time.sourceforge.net/faq.html#datediff
Aby obliczyć różnicę między dwoma datami i wywołać tę usługę z javascript.
Zakłada się, że Twój back end jest w Javie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-19 02:00:39