从时区偏移本地化日期时间(时区感知)
Posted
技术标签:
【中文标题】从时区偏移本地化日期时间(时区感知)【英文标题】:Localize datetime (timezone aware) from timezone offset 【发布时间】:2014-04-13 20:07:38 【问题描述】:我有一个 UTC 时间戳和一个时区偏移时间戳(均以毫秒为单位):
utc_time = 1394452800000
timezoneoffset = -14400000
如果我想获得datetime
,我会这样做:
print datetime.utcfromtimestamp(utc_time/1000)
>>>2014-03-10 12:00:00
我怎样才能本地化这个日期时间,但最终对象也能感知时区?
如果我除以timezoneoffset
,-14400000/(3600*1000) = -4(小时)。所以最终的输出应该是:
>>>2014-03-10 08:00:00-04:00
我的尝试:
from pytz import timezone
from dateutil.tz import tzoffset
utc_time = 1394452800000
timezoneoffset = -14400000
tzinfooff = tzoffset(None, timezoneoffset/1000)
print timezone(tzinfooff).localize( datetime.utcfromtimestamp(utc_time/1000) )
>>>Traceback (most recent call last):
File "/Users/dionysis_lorentzos/Desktop/cmdline copy.py", line 25, in <module>
print timezone(tzinfo2).localize( datetime.utcfromtimestamp(time/1000) ).isoformat()
File "/usr/local/lib/python2.7/site-packages/pytz/__init__.py", line 162, in timezone
if zone.upper() == 'UTC':
AttributeError: 'tzoffset' object has no attribute 'upper'
【问题讨论】:
08:00:00-04:00
?或12-4
?
timezone
没有偏移;我不确定是否有任何pytz
可以调用。
@zhangxaochen utc_time
时间戳在 UTC 时区而不是本地时区(如果我理解正确你的问题)。
@MartijnPieters 所以没有可能的解决方法?
我没这么说。 :-)
【参考方案1】:
您需要只使用dateutil.tz.tzoffset()
type; pytz.timezone
只接受 names,而不接受 dateutil.tz
对象。
.localize()
方法仅适用于pytz
提供的时区,因为它们也包含历史偏移量,并且需要将它们应用于datetime
对象,比.replace()
可以做的更小心.
如果时间戳是 UTC 中的 UNIX 纪元值,则使用 fromtimestap
和时区作为第二个参数:
>>> print datetime.fromtimestamp(utc_time/1000, tzinfooff)
2014-03-10 08:00:00-04:00
或者您可以翻译 UTC,使用datetime.astimezone()
:
>>> from dateutil.tz impor tzutc
>>> dt_utc = datetime.utcfromtimestamp(utc_time/1000).replace(tzinfo=tzutc())
>>> print dt_utc.astimezone(tzinfooff)
2014-03-10 08:00:00-04:00
【讨论】:
谢谢!我可以建议:print datetime.utcfromtimestamp((utc_time+timezoneoffset)/1000).replace(tzinfo=tzinfooff) >>>2014-03-10 08:00:00-04:00
。还是没有?
@Diolor:在这种情况下,您没有附加时区,而是在转换到不同的时区。使用 UTC 时区进行设置,然后使用 datetime.astimezone()
进行翻译。
我会选择datetime.fromtimestamp()
,谢谢
@Diolor:我非常同意。 :-)
使用local_dt = utcfromtimestamp(ts).replace(tzinfo=local_tz)
不正确【参考方案2】:
要将 POSIX 时间戳转换为由其 utc 偏移指定的时区中的时区感知日期时间对象,您可以创建一个感知 utc 日期时间对象并将其转换为固定偏移时区:
from datetime import datetime
utc_dt = datetime.fromtimestamp(utc_time * 1e-3, utc)
dt = utc_dt.astimezone(FixedOffset(timezoneoffset * 1e-3 / 60, None))
print(dt.isoformat(' '))
# -> 2014-03-10 08:00:00-04:00
其中utc
和FixedOffset
在datetime
docs 中定义:
from datetime import tzinfo, timedelta
class FixedOffset(tzinfo):
"""Fixed offset in minutes east from UTC."""
def __init__(self, offset, name):
self.__offset = timedelta(minutes = offset)
self.__name = name
def utcoffset(self, dt):
return self.__offset
def tzname(self, dt):
return self.__name
def dst(self, dt):
return timedelta(0)
utc = FixedOffset(0, "UTC")
【讨论】:
以上是关于从时区偏移本地化日期时间(时区感知)的主要内容,如果未能解决你的问题,请参考以下文章