我正在寻找有关日期的最佳做法 - 日期本身是重要的,而不是当天的特定时间。
一个很好的开始是这个问题: Daylight saving time and time zone best practices
我想要一些适用于我的情况的指导。我有药物从特定日期开始,到另一个日期结束。然后,我需要查询在给定日期范围内有效的药物。
我已尝试将开始日期和结束日期设置为当地时间午夜,然后以UTC格式存储在数据库中。我也可以添加时区条目。
我在客户端和服务器上都使用了moment.js,如果需要可以使用时刻。
我想知道如何处理DST对我的时间的影响 - 这使我在DST和非DST时段之间的当地午夜UTC时间产生一小时差异。
我遇到的问题是,例如某些药物在DST期间设定了结束日期,而某些药物在非DST期间设定了。然后,他们的UTC时间相差一小时。当对从当地午夜开始的特定日期范围进行查询时,它不准确,因为有两种不同的午夜表示。查询本身可以将午夜视为两个不同时间之一,具体取决于查询的年份。
最终结果是药物可能比它应该晚一天结束,或者提前一天结束。
一个简单但不稳定的解决方法是在标准(非DST)时间内将开始日期设置为凌晨1点,将结束日期设置为标准(非DST)时间晚上11:59,并在午夜进行查询。
或者,我应该检查每个查询的开始和结束日期,并确定每个日期的UTC偏移量是多少?
但我更愿意知道在这种情况下最佳做法是什么。感谢。
答案 0 :(得分:1)
moment.js中的JavaScript Date
对象和moment
对象都用于表示特定的时刻。换句话说,日期和时间。他们通过计算自Unix Epoch(1970年1月1日午夜)以来经过的毫秒数来内部跟踪时间 - 忽略闰秒。
这意味着,从根本上说,它们不是处理整个日历日期的最佳方式。如果您只有一个日期,并且使用日期+时间值来跟踪它,那么您可以随意指定一天中的某个时间来表示整个日期。通常,这是午夜 - 但正如您所指出的那样,这会导致夏令时问题。
考虑到在世界的某些地方(例如巴西),过渡发生在午夜 - 也就是说,在春天,时钟从11:59:59跳到01:00:00。如果您指定该日期的午夜,浏览器将向前跳转或向后跳转(取决于您使用的是哪个浏览器)!
如果您将当地的午夜日期转换为其他时区(例如UTC),您可以更改日期本身!如果必须使用日期+时间来存储仅限日期的值,请使用正午而不是午夜。这将缓解大多数(但不是全部)调整问题。
更好的想法是将整个日期视为整个日期。不要为它们分配时间,也不要尝试将它们调整为UTC。不要使用Date
或moment
。相反,将它们存储为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()
};
我希望这能让你开始。你提出了一个相当广泛的问题,所以我试着以解决主要问题的方式回答。如果您有更具体的内容,请更新您的问题,我会尽力回复。
如果您想了解有关此主题的更多信息,建议您观看我的Pluralsight课程Date and Time Fundamentals。