Get difference between 2 dates in JavaScript?
如何获得完整日期中2个日期之间的差异(我不想要一天中的任何一小部分)
1 2 3 4
| var date1 = new Date('7/11/2010');
var date2 = new Date('12/12/2010');
var diffDays = date2.getDate() - date1.getDate();
alert(diffDays) |
我尝试了以上但是这没用。
-
只是旁注:不要使用这些类型的字符串作为输入创建Date对象; 它是非标准的,取决于浏览器如何解析它们。 使用可由Date.parse解析的字符串,或者使用三个数值作为new Date的参数,例如new Date(2010, 11, 7);。
-
旁注:永远不要相信客户端的系统时间! 经常出错,你可能会破坏你的应用程序。
-
另外,在stackoverflow.com/a/53092438/3787376上尝试一个小功能。
这是一种方式:
1 2 3 4 5
| const date1 = new Date('7/13/2010');
const date2 = new Date('12/15/2010');
const diffTime = Math.abs(date2.getTime() - date1.getTime());
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
console.log(diffDays); |
请注意,我们需要将日期括在引号中。其余代码以毫秒为单位获取时间差,然后除以得到天数。日期需要mm / dd / yyyy格式。
-
啊引号是一个错字。我仍然像我的方式一样。
-
是什么(1000 * 3600 * 24)这些是什么(分钟?秒?小时?)
-
你的另一个问题是@volkan似乎没有问题,如果date2小于日期1你的将给出正数而不是负数。
-
正如volkan在下面回答的那样,1000 * 3600 * 24是每天的毫秒数。至于总是返回一个正数,这是一个特征:)通常当一个人谈到两个日期之间的天数时,这个数字是正数。如果方向很重要,只需删除Math.abs()即可。
-
同样,您使用您的方法获得1天,因为getDate()会返回与月份无关的日期。因此,你会得到12 - 11 = 1。
-
date已经返回的时间不需要调用.getTime()
-
@volkan呃:的确,你是对的。我永远记不起那样的事情。
-
为了使其能够正常使用夏令时,Math.round应该替换Math.ceil。但我认为Shyam的答案是要走的路。
-
@Zemljoradnik,你介意解释为什么它不起作用? getTime()返回UTC时间戳,为什么这不起作用?
-
@Dalius以上不起作用,因为Date构造函数在本地时区创建日期。因此,您通过getTime()获得的UTC时间戳,虽然是UTC值,但反映了日期的DST调整值。 IOW,垃圾出垃圾:-)
-
这是一个非常糟糕的答案,因为日期字符串的解析永远不应该留给Date构造函数。对于世界上大多数人来说,7/11/2010代表11月7日,但大多数浏览器将其视为7月11日。
-
2010年7月11日至12月12日期间155天?
-
我认为它应该是Math.floor而不是Math.ceil。因为Math.floor(120.12323)将返回120.而Math.ceil(120.1232144)将返回121。
-
在计算的范围内,无法使用23小时25小时。在设计诸如此类的计算之前,咨询UTC(通用协调时间)和"民用"时间标准的详细处理将是有帮助的。一天不总是86,400秒,甚至不是UTC。但是,ECMA标准规定,它不会在UTC中每年发生两次58,59,61或62秒。您不能假设其他语言和操作系统中的纪元(1970年1月1日00:00:00)之间的偏移将是相同的,因为其中一些具有58,59,61和62秒的分钟。
-
警告!这个"解决方案"总是给出正数,如果你想要一个过去的日期和当前日期之间的差异,那么这是错误的。
-
我用03/11/2017 - 29/10/2017尝试了这个,我有6天了。对于所有情况,Math.ceil都不是正确的解决方案。我过早地赞成这个答案。
-
如果两天不在同一GMT中,结果可能会出乎意料(当时区在一年中的某些时段发生变化时出错)
更正确的解决方案
...因为日期自然具有时区信息,可以跨越具有不同日光节约调整的区域
此问题的先前答案不考虑有问题的两个日期跨越夏令时(DST)更改的情况。 DST更改发生的日期将以毫秒为单位,!= 1000*60*60*24,因此典型计算将失败。
您可以通过首先将两个日期标准化为UTC,然后计算这两个UTC日期之间的差异来解决此问题。
现在,解决方案可以写成,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const _MS_PER_DAY = 1000 * 60 * 60 * 24;
// a and b are javascript Date objects
function dateDiffInDays(a, b) {
// Discard the time and time-zone information.
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
return Math.floor((utc2 - utc1) / _MS_PER_DAY);
}
// test it
const a = new Date("2017-01-01"),
b = new Date("2017-07-25"),
difference = dateDiffInDays(a, b); |
这是因为UTC时间从不观察夏令时。请参阅UTC是否遵守夏令时?
附:在讨论了关于这个答案的一些评论之后,一旦你理解了跨越DST边界的javascript日期的问题,可能不仅仅有一种方法可以解决它。我上面提供的是一个简单(和测试)的解决方案。我有兴趣知道是否有一个简单的算术/数学解决方案,而不必实例化两个新的Date对象。这可能会更快。
-
这是唯一正确的答案,我不明白为什么其他答案如果被接受
-
可能是因为@ chobo2没有回来看这个问题
-
@Ai_boy:虽然这是最正确的答案,但是没有值与更简单的Math.round((b - a)/ _MS_PER_DAY, 0)匹配,因此很难支持"唯一正确的答案"。
-
@ScottSauyet我们遇到的问题是当a和b跨越日光节约开关时。当你说"没有价值"时,你是否将其作为一个场景包含在内?
-
@ShyamHabarakada:这是一个Math.ceil或Math.floor技术的问题,但由于夏令时仅从24小时开始调整一小时,它将被Math.round吞噬。我没有详尽地测试过,但我看不出两者不同意的情况。你能?我们实际上是在18347050讨论这个问题,这是我如何遇到这个旧线程,我在那里提出了夏令时。
-
是的,舍入可能与您描述的一样,并假设a和b是同一时区中的值等,但在a和b是不在同一时区的日期时间对象的情况下失败。例如,尝试:var a = new Date("Mon Sep 09 2013 17:46:44 GMT+0800 (PDT)");和b = new Date("Mon Sep 09 2013 17:46:44 GMT-0700 (PDT)"),然后将Math.round技术应用于这些日期。
-
+1用于删除恼人的alert
-
如何在几小时内提供退货?
-
@Radio你能澄清一下你的意思吗?也许一个例子......
-
这个答案是对的。 Javascript日期对象是UTC。使用本地值生成UTC日期将忽略夏令时,因此如果差异应该是本地的,那么将日期视为UTC将消除夏令时(因此在夏令时边界上答案可能是错误的)。
-
@RobG这是一个有趣的场景,但我不确定我是否完全遵循。你能给我举个例子吗?我在一个应用程序中使用此代码,所以如果有错误,我真的想修复它:-)
-
假设Javascript在客户端运行,这个答案是非常复杂的。请阅读getTime()和UTC()。他们都从1970年1月1日午夜返回毫秒。
-
@Dr.DucNguyen先生我不确定你指的是什么。在代码中,Date.UTC用于construct UTC时区中的新日期对象。 has_initialized对象上的getTime()函数返回UTC的毫秒数。比较d1 = new Date(2015,1,1)和d2 = new Date(Date.UTC(2015,1,1));之间的差异,您将了解代码的作用。谢谢
-
@ShyamHabarakada我不确定你为什么要在评论中给出2个日期。他们显然是不同的。你能指出:t1 = (new Date(2015, 2, 1)).getTime()和t2 = Date.UTC(2015, 2, 1)之间的区别是什么?我们正在查看这些数字,以告知2个日期对象的不同。不是相反,不是吗?
-
使用UTC而不是当地时区将纠正民用时间系统中23小时和25小时的问题。 UTC也有58,59,61和62秒的分钟,一年两次,因此UTC的一天不会总是有86,400秒。但是,ECMA标准规定JavaScript不包含这些调整,因此在纯粹使用JavaScript工作时忽略它们。但是,其他系统不会忽略它们,并且您不能假设从纪元时刻(1970年1月1日00:00:00)的偏移量在编程语言和操作系统之间始终是相同的。
-
这很奇怪,但似乎在momentJS中没有这样的方法。有一个diff()方法,但它不计算实际的日历差异,因此例如moment('2015-04-24T14:00:00.000Z').diff(moment('2015-04-24T11:00:00.000Z'), 'days')将导致零,就这是否是同一日期而言显然不是真的。
-
@ Mr.DucNguyen我不确定我理解你的问题。您提供的示例的值为(new Date(2015, 2, 1)).getTime() => 1425196800000和Date.UTC(2015, 2, 1) => 1425168000000。转换为相同时区时,这些日期分别为Sun Mar 01 2015 00:00:00 GMT-0800 (PST)和Sat Feb 28 2015 16:00:00 GMT-0800 (PST)。并且这些日期之间的差异为1(如果您反转比较顺序,则为-1)。那有意义吗?
-
很棒的帮助。我同意@Ai_boy这个答案需要接受。在我使用标记为已接受的答案之前,但我没有得到我正在寻找的结果。我尝试接受日期为2015年6月15日和2015年10月17日的答案我得到的天差是122天,当我尝试你的代码时错误结果是124天及其正确。谢谢你这么好的答案+1。
-
@ ShyamHabarakada-"本地"日期对象在创建日期时考虑系统时区设置。内部值为UTC,因此如果某个地方在02:00更改为DST,并且当天日期为01:00和03:00创建,则时差(即两个日期的时间值之间)应为1小时,而不是2小时(从02:00开始瞬间变为03:00)。如果您使用UTC在01:00和03:00创建日期,则时差将为2小时,因为没有DST限额。但无论如何,如果OP只对整天感兴趣,那么四舍五入将解决DST差异,因为它不会超过1小时。
-
@RobG这是正确的。取决于你的四舍五入的意思......这就是上面的解决方案在某种程度上的作用。它需要任何日期并将其舍入到00:00:00的UTC分区日期,然后进行数学运算以找出差异。 OP表示他们希望在整天都能有所不同。考虑更多,我不知道除了整天之外,两天之间是否有任何其他差异定义。
-
@ ShyamHabarakada- OP没有表明对UTC的任何要求,只是使用没有时区或时间的日期,因此使用这些值来创建"本地"日期对象,减去,除以ms /天和舍入将产生完全相同的与使用UTC方法相同的结果。唯一的区别是UTC版本不需要舍入,因为它不会受到DST的影响,如果它在设置为观察它的系统上运行的话。
-
@RobG缺乏UTC要求不是问题。如果您在具有日光节省更改的时区中使用当前接受的解决方案中的错误,并且用作输入的日期会跨越此DST更改。 HTH
-
@ ShyamHabarakada-什么。如果只需要整天,Math.round((a-b)/8.64e7)就可以胜任。
-
另请参阅stackoverflow.com/questions/1968167/…对于类似的答案,其具有使得较低单位的值中的时间单位的最大总量和对于任何较高单位的数量的余数较低的单位(例如,获得整分钟和整个剩余的秒和毫秒)的函数。请注意,答案不包括有问题的两个日期跨越夏令时(DST)更改的情况。
-
@RobG再次问好:-)我没有按照你的想法在脑海里形成一个完整的答案。随意提交编辑或新答案。干杯,新年快乐。
-
这个解决方案很好地满足了我在AEM 6.2 Adaptive Forms中执行JS规则的需求。我需要以#天为单位返回日期差异,以及正面和负面结果。
-
var a = new Date(2017,9,25); var b = new Date(2017,10,6);对于这些日期,我得到12天差异,但是,变化a =新日期(2017,10,25); var b = new Date(2017,11,5);我要11天了。这是错的。我应该得到13天
-
@NallaSrinivas我测试了你的情况,看起来结果是正确的。请记住,在创建这些日期时,默认情况下,javascript会在给定日期的00:00:00创建日期时间对象。因此,当你给它"2017-11-05"时,它实际上是创建一个代表前一天午夜的日期对象,当计算差异时,它不会计入第05个。如果你想要包含第5个,你应该做+1。
-
这应列为已接受的答案。
-
应使用Math.trunc()代替Math.floor()来给出负数的正确结果(即当utc1 > utc2时)
-
但实际上,是否需要Math.floor/trunc?丢弃时间信息后,您是否总能获得返回的整数天数?
-
使用这种方法可以在几秒钟内获得差异吗?
-
@Notflip取决于你在几秒钟内的差异定义。如果您希望在一天内使用秒数乘以天数,则确定您可以利用此方法。但同样,答案取决于你的确切定义...... HTH
这是一个使用moment.js的解决方案:
1 2 3 4
| var a = moment('7/11/2010','M/D/YYYY');
var b = moment('12/12/2010','M/D/YYYY');
var diffDays = b.diff(a, 'days');
alert(diffDays); |
我使用了您的原始输入值,但您没有指定格式,所以我假设第一个值是7月11日。如果打算在11月7日,则将格式调整为D/M/YYYY。
-
干杯,我正在寻找一个瞬间的解决方案
-
@Matt Johnson:我需要找到确切的差异,我的意思是,从这个时间开始的未来日期剩余的天数,小时数,最小值和秒数?怎么做?
-
@ImdadAli - 请参阅stackoverflow.com/a/41876250/634824。
-
请注意,moment.js是一个很大的依赖
1 2 3 4 5
| var date1 = new Date("7/11/2010");
var date2 = new Date("8/11/2010");
var diffDays = parseInt((date2 - date1) / (1000 * 60 * 60 * 24));
alert(diffDays ) |
-
什么是1000 * 60 * 60 * 24?
-
date2 - date1 =>毫秒输出(1000 * 60 * 60 * 24)=>毫秒到天
-
完全不需要parseInt吗?
-
在天数方面获得全部价值;请求并将受工作相关...
-
克里斯蒂安:他想要一个整数。 parseInt可能是最糟糕的方式。 Math.round是'正常'的方式;它舍入而不是截断。如果需要截断,那么'或'表达式就足够了:(date2 - date1) / (1000 * 60 * 60 * 24) | 0
-
请注意,此解决方案并不完全准确,因为在某些情况下,即2015-04-06减去2015-04-04错误的1天,所有关于parseInt()的方法。
-
因为有些日子只有23个小时。
-
@ontananza var date1 = new Date("2015-04-04"); var date2 = new Date("2015-04-06"); parseInt((date2 - date1) / (1000 * 60 * 60 * 24));为我收益2
-
@GarrGodfrey你住在哪个星球上?
-
在夏令时的地区,每年有一天实际上只有23小时。
我尝试了很多方法,发现使用datepicker是最好的,但日期格式会导致JavaScript出现问题....
所以这是我的答案,可以开箱即用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| <input type="text" id="startdate">
<input type="text" id="enddate">
<input type="text" id="days">
<script src="https://code.jquery.com/jquery-1.8.3.js">
<script src="https://code.jquery.com/ui/1.10.0/jquery-ui.js">
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/redmond/jquery-ui.css" />
$(document).ready(function() {
$("#startdate,#enddate" ).datepicker({
changeMonth: true,
changeYear: true,
firstDay: 1,
dateFormat: 'dd/mm/yy',
})
$("#startdate" ).datepicker({ dateFormat: 'dd-mm-yy' });
$("#enddate" ).datepicker({ dateFormat: 'dd-mm-yy' });
$('#enddate').change(function() {
var start = $('#startdate').datepicker('getDate');
var end = $('#enddate').datepicker('getDate');
if (start<end) {
var days = (end - start)/1000/60/60/24;
$('#days').val(days);
}
else {
alert ("You cant come back before you have been!");
$('#startdate').val("");
$('#enddate').val("");
$('#days').val("");
}
}); //end change function
}); //end ready |
在这里可以看到小提琴演示
-
这与我遇到的问题类似的问题是,如果用户先点击date2 datepicker,那么它就会失败。
这是从另一个日期中减去一个日期的代码。此示例将日期转换为对象,因为getTime()函数将不起作用,除非它是Date对象。
1 2 3 4 5 6 7 8 9 10
| var dat1 = document.getElementById('inputDate').value;
var date1 = new Date(dat1)//converts string to date object
alert(date1);
var dat2 = document.getElementById('inputFinishDate').value;
var date2 = new Date(dat2)
alert(date2);
var oneDay = 24 * 60 * 60 * 1000; // hours*minutes*seconds*milliseconds
var diffDays = Math.abs((date1.getTime() - date2.getTime()) / (oneDay));
alert(diffDays); |