日期范围与JST中的DST

时间:2014-11-24 21:29:19

标签: javascript date datetime momentjs

我正在寻找有关日期的最佳做法 - 日期本身是重要的,而不是当天的特定时间。

一个很好的开始是这个问题: Daylight saving time and time zone best practices

我想要一些适用于我的情况的指导。我有药物从特定日期开始,到另一个日期结束。然后,我需要查询在给定日期范围内有效的药物。

我已尝试将开始日期和结束日期设置为当地时间午夜,然后以UTC格式存储在数据库中。我也可以添加时区条目。

我在客户端和服务器上都使用了moment.js,如果需要可以使用时刻。

我想知道如何处理DST对我的时间的影响 - 这使我在DST和非DST时段之间的当地午夜UTC时间产生一小时差异。

我遇到的问题是,例如某些药物在DST期间设定了结束日期,而某些药物在非DST期间设定了。然后,他们的UTC时间相差一小时。当对从当地午夜开始的特定日期范围进行查询时,它不准确,因为有两种不同的午夜表示。查询本身可以将午夜视为两个不同时间之一,具体取决于查询的年份。

最终结果是药物可能比它应该晚一天结束,或者提前一天结束。

一个简单但不稳定的解决方法是在标准(非DST)时间内将开始日期设置为凌晨1点,将结束日期设置为标准(非DST)时间晚上11:59,并在午夜进行查询。

或者,我应该检查每个查询的开始和结束日期,并确定每个日期的UTC偏移量是多少?

但我更愿意知道在这种情况下最佳做法是什么。感谢。

1 个答案:

答案 0 :(得分:1)

moment.js中的JavaScript Date对象和moment对象都用于表示特定的时刻。换句话说,日期和时间。他们通过计算自Unix Epoch(1970年1月1日午夜)以来经过的毫秒数来内部跟踪时间 - 忽略闰秒。

这意味着,从根本上说,它们不是处理整个日历日期的最佳方式。如果您只有一个日期,并且使用日期+时间值来跟踪它,那么您可以随意指定一天中的某个时间来表示整个日期。通常,这是午夜 - 但正如您所指出的那样,这会导致夏令时问题。

考虑到在世界的某些地方(例如巴西),过渡发生在午夜 - 也就是说,在春天,时钟从11:59:59跳到01:00:00。如果您指定该日期的午夜,浏览器将向前跳转或向后跳转(取决于您使用的是哪个浏览器)!

如果您将当地的午夜日​​期转换为其他时区(例如UTC),您可以更改日期本身!如果必须使用日期+时间来存储仅限日期的值,请使用正午而不是午夜。这将缓解大多数(但不是全部)调整问题。

更好的想法是将整个日期视为整个日期。不要为它们分配时间,也不要尝试将它们调整为UTC。不要使用Datemoment。相反,将它们存储为ISO-8601格式的字符串,如"2014-11-25",或者如果您需要对它们进行数学运算,请考虑将它们存储为整数天的整数,因为它有一些起始值。例如,使用相同的1970年1月1日纪元日期,我们可以使用以下JavaScript代表2014年11月11日16399

function dateToValue(year, month, day) {
    return Date.UTC(year, month-1, day) / 86400000;
}

function valueToDate(value) {
    var d = new Date(86400000 * value);
    return { year : d.getUTCFullYear(), 
             month : d.getUTCMonth() + 1,
             day : d.getUTCDate()
           };
}

在处理整个日期时还需要记住一些其他事项:

  • 使用整个日期的范围时,人们倾向于使用完全包容的间隔。例如,1月1日到1月2日将是两个天。这与日期+时间(和仅时间)范围不同,其中人类倾向于使用半开间隔。例如,1:00到2:00将一个小时。

  • 由于时区的原因,每个人的“今天”概念在全球各地都有所不同。我们通常用我们自己的当地时区来定义“今天”。通常如此:

    var d = new Date();
    var today = { year : d.getFullYear(), 
                  month : d.getMonth() + 1,
                  day : d.getDate()
                };
    
    • 通常不希望将其转换为UTC或其他时区,除非您的商家在该时区内全球运营。这种情况很少见,但确实会发生。 (例如,StackOverflow使用UTC天来计算徽章和其他成就。)

我希望这能让你开始。你提出了一个相当广泛的问题,所以我试着以解决主要问题的方式回答。如果您有更具体的内容,请更新您的问题,我会尽力回复。

如果您想了解有关此主题的更多信息,建议您观看我的Pluralsight课程Date and Time Fundamentals