将时区缩写解析为UTC

4

如何将形式为Feb 25 2010, 16:19:20 CET的日期时间字符串转换为Unix纪元?

目前我的最佳方法是使用time.strptime(),如下:

def to_unixepoch(s):
    # ignore the time zone in strptime
    a = s.split()
    b = time.strptime(" ".join(a[:-1]) + " UTC", "%b %d %Y, %H:%M:%S %Z")
    # this puts the time_tuple(UTC+TZ) to unixepoch(UTC+TZ+LOCALTIME)
    c = int(time.mktime(b))
    # UTC+TZ
    c -= time.timezone
    # UTC
    c -= {"CET": 3600, "CEST": 2 * 3600}[a[-1]]
    return c

我从其他问题中看到,可能可以使用calendar.timegm()pytz等工具来简化此过程,但这些工具不能处理缩写的时区。

我想要一种需要最少额外库的解决方案,尽可能使用标准库。


是的,我最终也采用了自己的任意时区缩写查找表。我认为一般情况是无法解决的,因为全球存在多个具有相同缩写的时区。 - bobince
@bobince:好的,很高兴知道我没有错过什么。我发现了这个很棒的链接,让我对我上面的方法更有信心:http://www.timeanddate.com/library/abbreviations/timezones/ - Matt Joiner
1个回答

7
Python标准库并没有真正实现时区。你应该使用python-dateutil。它为标准的datetime模块提供了有用的扩展,包括时区实现和解析器。
你可以使用.astimezone(dateutil.tz.tzutc())将时区感知的datetime对象转换为UTC。对于当前时间作为时区感知的datetime对象,你可以使用datetime.datetime.utcnow().replace(tzinfo=dateutil.tz.tzutc())
import dateutil.tz

cet = dateutil.tz.gettz('CET')

cesttime = datetime.datetime(2010, 4, 1, 12, 57, tzinfo=cet)
cesttime.isoformat()
'2010-04-01T12:57:00+02:00'

cettime = datetime.datetime(2010, 1, 1, 12, 57, tzinfo=cet)
cettime.isoformat() 
'2010-01-01T12:57:00+01:00'

# does not automatically parse the time zone portion
dateutil.parser.parse('Feb 25 2010, 16:19:20 CET')\
    .replace(tzinfo=dateutil.tz.gettz('CET'))

不幸的是,在重复的夏令时小时,这种技术将是错误的。


1
等等,什么?我以为Unix纪元是普遍适用的。0代表格林威治标准时间午夜,而在中欧时间则是凌晨1点。只有在转换成time_tuple时才涉及到本地化。 - Matt Joiner
您是正确的,time.time() 应该是 UTC 时间。 - joeforker
好的,谢谢您的确认。如果我错了,那将会让我心碎 :) - Matt Joiner
1
我建议你自己检查一下。维基百科上说应该是协调世界时(UTC)。 - joeforker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接