JavaScript 中两个日期之间的月份差异
-
22-09-2019 - |
题
如何计算 JavaScript 中两个 Date() 对象的差异,同时只返回差异的月数?
任何帮助都会很棒:)
解决方案
“中的差的月数”的定义是受到了很多解释。 : - )
您可以从一个JavaScript日期对象获得的年,月,月的一天。根据您正在寻找什么样的信息,您可以使用这些找出多少个月的时间是两点之间。
例如,现成的,袖套,此发现多少完整月两个日期,不计算局部个月(例如,不包括该月的每个日期是)之间谎言:
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月份值从0开始=一月。)
包含在上述分数个月要复杂得多,因为三天典型二月是一个月(〜10.714%)超过三天的八月(〜9.677%)的较大部分,当然甚至二月是一个取决于它是否是闰年移动的目标。
也有一些日期和时间库使用为JavaScript,可能使这个事情变得更为简单。
其他提示
如果你不考虑该月的一天,这是迄今为止简单的解决方案
function monthDiff(dateFrom, dateTo) {
return dateTo.getMonth() - dateFrom.getMonth() +
(12 * (dateTo.getFullYear() - dateFrom.getFullYear()))
}
//examples
console.log(monthDiff(new Date(2000, 01), new Date(2000, 02))) // 1
console.log(monthDiff(new Date(1999, 02), new Date(2000, 02))) // 12 full year
console.log(monthDiff(new Date(2009, 11), new Date(2010, 0))) // 1
注意,月份索引是基于0。这意味着January = 0
和December = 11
。
有时你可能想要得到之间两个日期完全不顾一天部分月份不仅仅是数量。因此,举例来说,如果你有两个dates- 2013年6月21日和2013年/ 10 / 18-和你只关心在2013/06和10分之2013部分,这里的情况和可能的解决方案:
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.如果你只想要排除双方MONTH1两个日期之间的月数和MONTH2
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) - 1;
2。如果你想要么包含月份的
numberOfMonths = (year2 - year1) * 12 + (month2 - month1);
3,如果你想既包括个月的
numberOfMonths = (year2 - year1) * 12 + (month2 - month1) + 1;
下面是一个函数,它准确地提供2个日期之间的月数。结果
默认行为只计算整月,例如3个月1天将导致3个月的差别。您可以通过设置roundUpFractionalMonths
PARAM作为true
防止这一点,所以3个月零1天差将在4个月返还。
<强>上述(T.J.克劳德的回答)接受的答案是不准确的,有时返回错误的值。强>
例如,monthDiff(new Date('Jul 01, 2015'), new Date('Aug 05, 2015'))
返回0
这显然是错误的。正确的差为1整月或2个月舍入。
下面是我写的函数:
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);
};
如果您需要计算完整月份,无论月份是 28、29、30 还是 31 天。下面应该可以工作。
var months = to.getMonth() - from.getMonth()
+ (12 * (to.getFullYear() - from.getFullYear()));
if(to.getDate() < from.getDate()){
months--;
}
return months;
这是答案的扩展版本 https://stackoverflow.com/a/4312956/1987208 但修复了从 1 月 31 日到 2 月 1 日(1 天)的情况计算 1 个月的情况。
这将涵盖以下内容;
- 1 月 1 日到 1 月 31 日 ---> 30 天 ---> 将得到 0(符合逻辑,因为这不是一个完整的月份)
- 2 月 1 日至 3 月 1 日 ---> 28 或 29 天 ---> 将得到 1(符合逻辑,因为这是一个完整的月份)
- 2 月 15 日至 3 月 15 日 ---> 28 或 29 天 ---> 将得到 1(自一个月过去以来符合逻辑)
- 1 月 31 日至 2 月 1 日 ---> 1 天 ---> 将得到 0(显而易见,但帖子中提到的答案会在 1 个月内产生)
在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)
start_date和end_date之间总月:
total_months = (end_date.getFullYear() - start_date.getFullYear())*12 + (end_date.getMonth() - start_date.getMonth())
我知道这是真的晚了,但以防万一反正张贴它可以帮助别人。这里是我想出了似乎做的计数差异搞好几个月两个日期之间的功能。这毫无疑问是个很大的邋遢比Mr.Crowder的,而是通过Date对象步进提供更准确的结果。它是在AS3,但你应该能够删除的强类型,你就会有JS。随意让它更好看的人在那里!
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;
}
考虑以月计的每个日期,然后减去找到的差异。
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());
这将让你在两个日期之间的月差,忽略日子。
要扩大@ T.J.的答案,如果你正在寻找简单的几个月,而不是完整的日历月,你可以只检查是否D2的日期是大于或等于比D1的。也就是说,如果D2是后来在其月比D1是在一个月,再有1个月以上。所以,你应该能够只是这样做:
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
这不能完全解释时间问题(例如3月3日下午4:00和4月3日下午3点),但它更精确和代码,就两行。
有两种方法,数学和快,但受制于变化无常在日历,或迭代&缓慢,但处理所有的奇特(或者至少代表他们处理到良好测试库)。
如果您通过迭代日历,以一个月为增加的开始日期及如果我们通过结束日期看到。这代表异常处理的内置日期()类,但可能是缓慢的如果的你这样做是对大量日期。詹姆斯的回答采取了这种办法。虽然我不喜欢这个想法,我认为这是“最安全”的方针,如果你只是在做的一个的计算,性能差异实在是可以忽略不计。我们倾向于尽量将只有一次进行过优化的任务。
现在,如果你在一个数据集计算此功能,您可能不希望运行在每一行(或上帝保佑,多次每条记录)该功能。在这种情况下,你几乎可以使用任何其他的答案在这里的除了的接受的答案,这是错误的(new Date()
和new Date()
之间的区别是-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;
}
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;
}
计算两个日期之间的差包括月(天)级分。
var difference = (date2.getDate() - date1.getDate()) / 30 +
date2.getMonth() - date1.getMonth() +
(12 * (date2.getFullYear() - date1.getFullYear()));
例如:结果 的日期1 强>:24/09/2015(2015年9月24日),点击 的 DATE2 强>:2015年9月11日(2015年11月9日),点击 的差:2.5(月)
此应该正常工作:
function monthDiff(d1, d2) {
var months;
months = (d2.getFullYear() - d1.getFullYear()) * 12;
months += d2.getMonth() - d1.getMonth();
return months;
}
您也可以考虑这种解决方案,这function
返回整数或数
传递的 开始日期 强>作为第一个或最后param
,是容错的。意,则该函数将返回仍然相同的值。
const diffInMonths = (end, start) => {
var timeDiff = Math.abs(end.getTime() - start.getTime());
return Math.round(timeDiff / (2e3 * 3600 * 365.25));
}
const result = diffInMonths(new Date(2015, 3, 28), new Date(2010, 1, 25));
// shows month difference as integer/number
console.log(result);
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);
}
通过取部分月份的天NR考虑以及下面的代码返回两个日期之间整月。
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
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;
}
下面逻辑将在数月取差
(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
function monthDiff(date1, date2, countDays) {
countDays = (typeof countDays !== 'undefined') ? countDays : false;
if (!date1 || !date2) {
return 0;
}
let bigDate = date1;
let smallDate = date2;
if (date1 < date2) {
bigDate = date2;
smallDate = date1;
}
let monthsCount = (bigDate.getFullYear() - smallDate.getFullYear()) * 12 + (bigDate.getMonth() - smallDate.getMonth());
if (countDays && bigDate.getDate() < smallDate.getDate()) {
--monthsCount;
}
return monthsCount;
}
请参阅我使用的是什么:
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;
}
这也算日子,并将其转换几个月。
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
对于繁荣,
使用 Moment.js 可以通过执行实现这一点:
const monthsLeft = moment(endDate).diff(moment(startDate), 'month');
anyVar = (((DisplayTo.getFullYear() * 12) + DisplayTo.getMonth()) - ((DisplayFrom.getFullYear() * 12) + DisplayFrom.getMonth()));
一种方法是将写一个简单的Java Web服务(REST / JSON),其使用JODA文库
http://joda-time.sourceforge.net/faq.html#datediff
两个日期和呼叫之间计算差从JavaScript服务。
这假设你的后端是Java。