多年来,我对一天结束时的不同解释。 但是在比较日期和时间间隔时,正确的方式是什么?
我发现有些人似乎更喜欢 23:59:59 ,而其他人则使用 00:00:00 。 在StackOverflow上,我甚至发现了一些与 24:00:00 的使用和显示相关的问题实例,但是这个问题的范围更侧重于确定如何分割两天。 / p>
换句话说,我们感兴趣的是确定一天结束的时间以及下一个开始的地方的问题。这似乎是许多应用中的常见问题,甚至需要最基本的时间间隔比较或计算。
为澄清上述解释,下面是三个代表2014年1月1日 st 的三个不同解释的例子:
2014-01-01 00:00:00 - 2014-01-01 23:59:59
2014-01-01 00:00:00 - 2014-01-02 00:00:00
2014-01-01 00:00:00 - 2014-01-01 24:00:00
虽然我觉得准午夜解释是最直观的解释,但似乎还需要相当数量的样板来正确指出时间。此外,当一天的最后一秒没有得到正确处理时,还存在遇到边缘情况的风险,或者在扫描大量间隔时间以便在这些间隙周围进行测试时影响性能的风险。
同样,军事午夜解释似乎也需要一些样板来设置该分割点的双重表示。没有太多的想法,我无法想到使用这种方法的许多复杂情况。
最后,午夜敏锐的解释似乎是最一致的解释。与午夜准不同,它不需要样板来设置时间,它自然地表现为操作符<
,<=
,>
和>=
。
值得注意的是,PHP语言已将2014-01-01 24:00:00
解释为2014-01-02 00:00:00
,这会将日期转换为午夜敏锐解释。
典型的FLOSS图书馆或标准中是否有明显的先例可以证明使用一种解释而不是另一种解释?
答案 0 :(得分:6)
00:00:00
是新一天的开始。
23:59:59
是过去的最后一秒,但还有一秒钟,所以23:59:59.999
是过去的最后一毫秒。尽管如此,它仍然不是最后一天,还有1毫秒的时间。
这取决于你需要做什么。如果你想检查事件是否在午夜之前发生(例如你正在查询MySQL数据库),那么新一天开始时的<
运算符就可以了,因为它可以满足你的任何粒度(纳秒,微秒,等等。
如果您想检查新的一天是否发生了某些事情,那么必须>=
新一天的开始,即00:00:00
答案 1 :(得分:6)
首先让我们回忆一下数学中的open and closed intervals:
- 开放时间间隔不包括其端点,并用括号表示。例如,
(0,1)
表示大于0且小于1。- 闭合间隔包括其端点,并用方括号表示。例如,
[0,1]
表示大于或等于0且小于或等于1.
我认为没有人会不同意这一天从00:00:00.000000...
开始。这意味着任何秒,毫秒,微秒等之前到那一点落在前一天。
我们通过使用左闭和右开间隔来表达这个概念。所以:
2014年1月1日这一天的时间跨度为
["2014-01-01 00:00:00", "2014-01-02 00:00:00")
这意味着午夜敏锐是正确的。但是,这需要您的机器具有无限分辨率,以便在第二天00:00:00
之前代表所有真正的,非常小的时间单位。
由于没有数字系统可以有无限分辨率,我们不得不承认准午夜,这将是一个关闭间隔。右端点的确切值取决于系统的分辨率。
正如迈克所说:
2014年1月1日这一天的时间为
["2014-01-01 00:00:00", "2014-01-02 00:00:00"-system_resolution]
如果您的环境/语言/数据结构仅提供一秒钟的分辨率,则当天的最后时刻为23:59:59
。对于1毫秒的分辨率,这将是23:59:59.999
。
所以从本质上讲,准午夜和午夜敏锐都是正确的,但准午夜的终点取决于你的分辨率。
在实践中,我认为你不必担心它!只需使用您的语言提供的DateTime
类对象/ API,以及相应的条件运算符(伪代码):
if DateTime.Now() < DateTime("2000-01-01 00:00:00"):
// Worry about Y2K bugs
答案 2 :(得分:2)
嗯,“代表它的正确方法是什么?”是一个主观问题,所以不可能回答。也就是说,大多数“时钟”应用程序和系统时钟都将其表示为上面的“准午夜”,所以如果您想要一致地向用户表示时间,那么您可能应该使用它。
但是,如果您没有直接向用户显示时间,而是将其用作其他计算的一部分,则可能是特定于应用程序的。
答案 3 :(得分:2)
毕竟,用抽象的术语来解决任何问题都很容易。
话虽如此,我个人更喜欢严格的小于(&lt;)00:00:00
答案 4 :(得分:1)
日期时间数据类型传统上表示为浮点数。整数部分是从预定时期开始的天数,尾数或小数部分构成时间偏移。有许多不同的时期和许多不同的方式来存储日期时间。我主要观察的是01/01/2001 12:00:00 AM和当天结束时间为01/01/2001 11:59:59 PM。
考虑它的一个好方法是从午夜减去一秒钟将是前一天的11:59:59,然后再添加第二天它将再次是午夜。
使用上述时期以相同方式存储特定日期午夜的值。 12小时24小时Zulu语义只是选择日期时间值的显示设置。