Python麻烦将毫秒转换为日期时间并返回
Posted
技术标签:
【中文标题】Python麻烦将毫秒转换为日期时间并返回【英文标题】:Python trouble converting milliseconds to datetime and back 【发布时间】:2015-07-03 09:44:57 【问题描述】:所以我有两个函数用于将 python datetime.datetime()
对象转换为毫秒数。我无法弄清楚这是哪里出了问题。这是我正在使用的:
>>> import datetime
>>> def mil_to_date(mil):
"""date items from REST services are reported in milliseconds,
this function will convert milliseconds to datetime objects
Required:
mil -- time in milliseconds
"""
if mil == None:
return None
elif mil < 0:
return datetime.datetime.utcfromtimestamp(0) + datetime.timedelta(seconds=(mil/1000))
else:
return datetime.datetime.fromtimestamp(mil / 1000)
>>> def date_to_mil(date):
"""converts datetime.datetime() object to milliseconds
date -- datetime.datetime() object"""
if isinstance(date, datetime.datetime):
epoch = datetime.datetime.utcfromtimestamp(0)
return long((date - epoch).total_seconds() * 1000.0)
>>> mil = 1394462888000
>>> date = mil_to_date(mil)
>>> date
datetime.datetime(2014, 3, 10, 9, 48, 8) #this is correct
>>> d2m = date_to_mil(date)
>>> d2m
1394444888000L
>>> mil
1394462888000L
>>> date2 = mil_to_date(d2m)
>>> date2
datetime.datetime(2014, 3, 10, 4, 48, 8) #why did I lose 5 hours??
由于某种原因,我失去了 5 个小时。我是否忽略了一些明显的东西?还是我的一项或两项功能有问题?
【问题讨论】:
这是因为fromtimestamp
返回本地时间:“如果可选参数tz为None或未指定,则时间戳转换为平台的本地日期和时间,返回的datetime对象是naive”
无关:timedelta(milliseconds=mil)
工作。
相关:Get current time in milliseconds in Python?
无关:即使结果是long
,你也可以使用int(2**300)
。
1394462888000 != 1394444888000
【参考方案1】:
原因是date_to_mil
可以与UTC
一起使用,而mil_to_date
不能。您应该将utcfromtimestamp
替换为fromtimestamp
。
进一步解释:
在您的代码中,epoch
是 UTC 纪元的日期(但该对象没有任何时区)。但是date
是本地时间,因为fromtimestamp 返回本地时间:
如果可选参数 tz 为 None 或未指定,则时间戳为 转换为平台的本地日期和时间,并返回 datetime 对象很幼稚
因此,您从本地日期时间中减去 UTC 纪元,您会得到一个延迟,即您对 UTC 的本地延迟。
【讨论】:
哦,哇,我错过了一些明显的东西!我应该将两者都视为UTC。我没有注意到纪元之后所有日期的 else 语句都没有使用.utcfromtimestamp()
方法。谢谢!
@crmackey:应该强调的是,从本地日期时间中减去 UTC 纪元就像从公斤中减去磅 - 结果是无意义的(应该从 utc 时间中减去 utc 纪元。如果本地时区过去有不同的 UTC 偏移量,然后对表示具有不同 UTC 偏移量的本地时间的原始日期时间对象执行算术也是错误的。请参阅Find if 24 hrs have passed between datetimes)【参考方案2】:
如果input is UTC then to get POSIX timestamp 为整数毫秒:
from datetime import datetime, timedelta
def timestamp_millis(utc_time, epoch=datetime(1970, 1, 1)):
"""Return milliseconds since Epoch as integer."""
td = utc_time - epoch
return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) // 10**3
注意:公式可能会产生与int(td.total_seconds() * 1000)
不同的结果。
反过来:从以毫秒为单位的 POSIX 时间获取 UTC 时间:
def datetime_from_millis(millis, epoch=datetime(1970, 1, 1)):
"""Return UTC time that corresponds to milliseconds since Epoch."""
return epoch + timedelta(milliseconds=millis)
它支持正负millis
。
注意:None
处理发生在这些函数之外。
例子:
>>> datetime_from_millis(1394462888000)
datetime.datetime(2014, 3, 10, 14, 48, 8)
>>> datetime.utcfromtimestamp(1394462888)
datetime.datetime(2014, 3, 10, 14, 48, 8)
>>> timestamp_millis(_)
1394462888000
结果与你的问题不同!
gmtime(0).year != 1970
和 TZ=right/UTC
的情况会被忽略。
【讨论】:
以上是关于Python麻烦将毫秒转换为日期时间并返回的主要内容,如果未能解决你的问题,请参考以下文章