将 unixtime 转换为 datetime 对象并再次返回(时间转换函数对)
Posted
技术标签:
【中文标题】将 unixtime 转换为 datetime 对象并再次返回(时间转换函数对)【英文标题】:Convert a unixtime to a datetime object and back again (pair of time conversion functions that are inverses) 【发布时间】:2012-10-26 23:40:09 【问题描述】:我正在尝试编写一对函数,dt
和 ut
,它们在正常的 unix 时间(自 1970-01-01 00:00:00 UTC 以来的秒数)和 Python 日期时间之间来回转换对象。
如果 dt
和 ut
是正确的逆,那么这段代码将打印两次相同的时间戳:
import time, datetime
# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.fromtimestamp(u)
def ut(d): return time.mktime(d.timetuple())
u = 1004260000
print u, "-->", ut(dt(u))
唉,第二个时间戳比第一个少 3600 秒(一个小时)。
我认为这只发生在非常特殊的 unixtime 上,也许在夏令时跳过的那个小时内。
但是有没有办法写出dt
和ut
,所以它们是彼此真正的倒数?
相关问题:Making matplotlib's date2num and num2date perfect inverses
【问题讨论】:
顺便说一句,如果函数什么都不做,只是用相同的参数调用另一个函数,那么你可以分配它:dt = datetime.datetime.utcfromtimestamp
。函数是 Python 中的一等公民:您可以将它们作为参数传递给另一个函数、从函数返回等。
啊,很好,很好!这样做更有效还是只是简洁的问题? def f(x): return foo(x)
与 f = lambda x: foo(x)
怎么样? (我记得它们在功能和效率方面都是等效的。)
f = g
表示 f,g 是指同一个函数的两个名称。 def
和 lambda
创建新函数。
【参考方案1】:
您是正确的,此行为与夏令时有关。避免这种情况的最简单方法是确保您使用没有夏令时的时区,UTC 在这里最有意义。
datetime.datetime.utcfromtimestamp()
和 calendar.timegm()
处理 UTC 时间,并且是精确的倒数。
import calendar, datetime
# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.utcfromtimestamp(u)
def ut(d): return calendar.timegm(d.timetuple())
以下是为什么datetime.datetime.fromtimestamp()
存在夏令时问题的一些解释,来自文档:
返回POSIX时间戳对应的本地日期时间, 例如由
time.time()
返回。如果可选参数 tz 为 None 或 未指定,时间戳转换为平台的本地日期 和时间,返回的 datetime 对象是幼稚的。
这里的重要部分是你得到一个幼稚的datetime.datetime
对象,这意味着对象中没有时区(或夏令时)信息。这意味着在使用 fromtimestamp()
时,多个不同的时间戳可以映射到同一个 datetime.datetime
对象,如果您碰巧选择了在夏令时回滚期间的时间:
>>> datetime.datetime.fromtimestamp(1004260000)
datetime.datetime(2001, 10, 28, 1, 6, 40)
>>> datetime.datetime.fromtimestamp(1004256400)
datetime.datetime(2001, 10, 28, 1, 6, 40)
【讨论】:
ut = lambda naive_utc_dt: (naive_utc_dt - datetime(1970,1,1)).total_seconds()
@J.F.Sebastian,想要添加它作为答案吗?听起来你是对的(虽然我没有验证你的版本),你的应该是这里接受的答案。我讨厌把后代误入歧途,只有 cmets 中的链接指向更好的方法!
@dreeves:点击链接查看更多详情。如果您不需要微秒,则基于 timegm() 的解决方案是可以的以上是关于将 unixtime 转换为 datetime 对象并再次返回(时间转换函数对)的主要内容,如果未能解决你的问题,请参考以下文章