【问题标题】:Calculate difference between 2 dates considering Daylight Saving Time考虑夏令时计算两个日期之间的差异
【发布时间】:2014-10-07 15:15:45
【问题描述】:

给定开始日期和天数,我需要显示结束日期 = 开始日期 + 天数。

所以我做了这样的事情:

var endDate=new Date(startDate.getTime()+ONE_DAY);

一切正常,除了 10 月 25 日和 26 日少了一天。

例如:

2014-01-01 + 2 days = 2014-01-03

2014-10-25 + 2 days = 2014-10-26 (here is the case I need to treat).

出现这种差异是因为时钟倒退了 1 小时。实际上2014-10-27 00:00:00 变成了2014-10-26 23:00:00

一个简单的解决方案是在另一个小时(例如凌晨 3 点)计算它。但我只想在发生这种情况时显示一个注释。

例如,如果用户输入 2014-10-25,我会显示一个弹出窗口,说 [something]。

现在真正的问题来了……我似乎找不到任何算法可以说明时钟何时回到 X 年。

例如...在 2014 年,这一天是 10 月 26 日。 2016 年是 10 月 30 日 (https://www.gov.uk/when-do-the-clocks-change)。为什么?这个日期看起来是随机的,但我不这么认为。那么......时钟什么时候回退/前进?

编辑:所有答案/cmets 都有助于解决问题。但是……我已经过了那个阶段。现在我只对“时钟改变的日子到底是怎么计算出来的?”很感兴趣。

【问题讨论】:

  • 如果你不反对使用库,我强烈推荐 moment.js 和 moment timezone,它在处理这类情况时消除了很多麻烦 (momentjs.com)
  • 夏令时不是基于特定日期,它通常是特定月份的第一个星期日的 02:00,随着地方采用或停止使用它而频繁变化,或者只是改变它开始的一周因为这似乎是个好主意。没有一致性,尽管赤道附近的国家往往不会比两极附近的国家更多地使用它。

标签: javascript date clock hour


【解决方案1】:

要找出两个日期之间的差异,请创建 Date 对象,从另一个中减去一个,然后除以一天中的毫秒数并取整。夏时制的剩余时间只差 1 小时,因此将四舍五入到正确的值。

您可能还需要一个小函数来将字符串转换为日期:

// Return Date given ISO date as yyyy-mm-dd
function parseISODate(ds) {
  var d = ds.split(/\D/);
  return new Date(d[0], --d[1], d[2]);
}

获取天差:

function dateDiff(d0, d1) {
  return Math.round((d1 - d0)/8.64e7);
}

// 297
console.log(dateDiff(parseISODate('2014-01-01'), parseISODate('2014-10-25')));

如果您想为日期添加天数,请执行以下操作:

// Add 2 days to 2014-10-25
var d = new Date(2014, 9, 25);
d.setDate(d.getDate() + 2);

console.log(d);   // 2014-10-27

内置的 Date 对象考虑了夏令时(认为在某些浏览器中存在错误)。

【讨论】:

    【解决方案2】:

    我更喜欢这样添加天数:

        var startDate = //someDate;
    
        var endDate = new Date(startDate.getFullYear(),
                   startDate.getMonth(),
                   startDate.getDate()+1);
    

    这样您就不必担心日历中的日期。

    此代码添加 1 天,如果您想添加更多,请将 startDate.getDate()+1 更改为 startDate.getDate()+NUMBER_OF_DAYS,即使您在每月的最后一天(即 10 月 31 日)也可以正常工作。

    但也许你可以使用比我的更优雅的@RobG 解决方案

    【讨论】:

    • 不,.getMonth() 为您提供基于 0 索引的月份,我的意思是从 0 到 11,但是当您使用 new 时,您必须将月份放在 1-12:w3schools.com/jsref/jsref_getmonth.asp跨度>
    • 我不想自大,但我的链接字面意思是:“定义和用法 getMonth() 方法根据当地时间返回指定日期的月份(从 0 到 11) 。”这就是我在评论中所说的。在 ECMAScript 引用中还说:“月数月由 0 到 11 范围内的整数标识,包括 0 到 11。从时间值 t 到月数的映射 MonthFromTime(t) 定义为:”ecma-international.org/ecma-262/5.1/#sec-15.9.1.4跨度>
    • 我测试过,你是对的!我做了 new Date(2000,1,1) 它实例化了 2 月 1 日,而不是 1 月 1 日。一个神话刚刚为我而死!感谢您提供的信息,并为您的固执感到抱歉!我去编辑一下。顺便说一句,我更喜欢你的更优雅的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2010-10-23
    • 2021-11-25
    • 2011-08-01
    • 2016-09-17
    • 1970-01-01
    • 2018-02-04
    相关资源
    最近更新 更多