【问题标题】:How to check if it's xx:00:00 with a timestamp?如何检查它是否是带有时间戳的 xx:00:00?
【发布时间】:2018-06-27 22:39:16
【问题描述】:

似乎检查它是否是 xx:00:00 UTC/GMT 就像检查 timestamp % 3600 == 0 是否一样简单,时间戳 = 自 epoch (1970-01-01 00:00:00) 以来经过的秒数.我们可以在这里看到:

import datetime 
print datetime.datetime.fromtimestamp(3600*24*17000)
# 2016-07-18 02:00:00

但这不是与leap seconds 矛盾吗?实际上,从 1970-01-01 00:00:00 到 2016-07-18 02:00:00 之间经过的秒数不是 3600 的倍数,而是的倍数3600 + 26 闰秒(从 1972 年到现在有 26 个闰秒)。


更准确地说:1970-01-01 00:00:00 和 2016-07-18 02:00:00 之间经过的秒数是 3600*24*17000 + 26 而不是 3600*24*17000.

【问题讨论】:

  • 许多(大多数?)计算机系统跟踪Unix Time
  • 为什么需要这个?如果要在午夜(或一天中的其他时间)运行一些代码,有更好的方法。
  • @Thomas 我知道cron 和类似的 Python 调度工具,但我不需要它,我只是想知道 UNIX 时间戳是如何工作的。

标签: python datetime time utc leap-second


【解决方案1】:

Python 的 datetime.datetime 对象无法处理闰秒,因为 seconds 属性被限制在 0..59 范围内:

In [19]: DT.datetime(2012, 6, 30, 23, 59, 60)
ValueError: second must be in 0..59

(2012-06-30 午夜前有闰秒)。

因此,Python 的日期时间系统并不能完全代表现实世界中存在的所有时间。它模拟了一个不存在闰秒的简化世界。

另请参阅:此 python issue 以“无法修复”状态关闭。

链接页面显示mxDatetime 作为datetime.datetime 的替代品,sort of 可以处理闰秒。

【讨论】:

  • 是的,但这意味着 1) Python 的日期时间/时间戳与其他语言中的其他 UNIX 时间戳实现不同(那会很糟糕,我认为情况并非如此)或 2) 所有 UNIX时间戳实现通常不关心闰秒。那么在实时和从 UNIX 时间戳中提取的时间之间是否存在缓慢的“漂移”?
  • Howard Hinnant's comment 所有 UNIX 时间戳都忽略闰秒。
  • It seems 它不会忽略它们@unutbu,它会通过在出现时跳回 1 秒的时间戳来处理它们。
  • @Basj:也许我说 UNIX 时间戳忽略闰秒是错误的。 UNIX 时间戳会回滚以考虑闰秒。现在的问题是,您有两个由同一个 UNIX 时间戳表示的真实时刻。 Python 使用系统的localtime 将时间戳转换为可能识别也可能不识别闰秒的日期。 This code 显示 Python 将秒数 >= 60 缩短到 59 秒,因此忽略闰秒。
【解决方案2】:

终于找到了here:

当插入闰秒时,平均大约每年半年发生一次,在闰秒期间Unix时间数不断增加,在此期间自当天开始以来已超过86,400秒,然后在闰秒结束时回退1,也就是第二天的开始

1998-12-31T23:59:59.75  915 148 799.75
1998-12-31T23:59:60.00  915 148 800.00  # leap second here
1998-12-31T23:59:60.25  915 148 800.25
1998-12-31T23:59:60.50  915 148 800.50
1998-12-31T23:59:60.75  915 148 800.75
1999-01-01T00:00:00.00  915 148 800.00  # timestamp jumps back!
1999-01-01T00:00:00.25  915 148 800.25

所以datetime.py 中的某处可能有一些代码可以进行闰秒检测+跳回。有一个对“闰秒”here 的引用,但我看不出它如何检测它是否为一。

import datetime 
print datetime.datetime.fromtimestamp(915148799) #1999-01-01 00:59:59
print datetime.datetime.fromtimestamp(915148800) #1999-01-01 01:00:00

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-03-26
  • 1970-01-01
  • 2019-07-26
  • 2014-09-16
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 1970-01-01
相关资源
最近更新 更多