将 UTC 日期时间字符串转换为本地日期时间

新手上路,请多包涵

我从来不需要在 UTC 之间转换时间。最近有一个请求让我的应用程序能够识别时区,而我一直在兜圈子。很多关于将本地时间转换为 UTC 的信息,我发现这些信息相当初级(也许我也做错了),但我找不到任何关于轻松将 UTC 时间转换为最终用户时区的信息。

简而言之,android 应用程序向我(appengine 应用程序)发送数据,并且该数据中有一个时间戳。要将该时间戳存储为我正在使用的 utc 时间:

 datetime.utcfromtimestamp(timestamp)

这似乎有效。当我的应用程序存储数据时,它会提前 5 小时存储(我是 EST -5)

数据存储在 appengine 的 BigTable 中,当检索到它时,它会以字符串形式出现,如下所示:

 "2011-01-21 02:37:21"

如何将此字符串转换为用户正确时区的 DateTime?

另外,用户时区信息的推荐存储是什么? (您通常如何存储 tz 信息,即:“-5:00”或“EST”等等?)我确定我的第一个问题的答案可能包含第二个答案的参数。

原文由 MattoTodd 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 375
2 个回答

如果您不想提供自己的 tzinfo 对象,请查看 python-dateutil 库。它提供 tzinfozoneinfo (Olson) 数据库 之上的实现,这样您就可以通过某种规范的名称来引用时区规则。

 from datetime import datetime
from dateutil import tz

# METHOD 1: Hardcode zones:
from_zone = tz.gettz('UTC')
to_zone = tz.gettz('America/New_York')

# METHOD 2: Auto-detect zones:
from_zone = tz.tzutc()
to_zone = tz.tzlocal()

# utc = datetime.utcnow()
utc = datetime.strptime('2011-01-21 02:37:21', '%Y-%m-%d %H:%M:%S')

# Tell the datetime object that it's in UTC time zone since
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
central = utc.astimezone(to_zone)

编辑 扩展示例以显示 strptime 用法

编辑 2 固定 API 用法以显示更好的入口点方法

编辑 3 包含时区自动检测方法 (Yarin)

原文由 Joe Holloway 发布,翻译遵循 CC BY-SA 3.0 许可协议

这是一个不依赖于任何外部库的弹性方法:

 from datetime import datetime
import time

def datetime_from_utc_to_local(utc_datetime):
    now_timestamp = time.time()
    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
    return utc_datetime + offset

这避免了 DelboyJay 示例中的计时问题。 Erik van Oosten 修正案中的时间问题较少。

作为一个有趣的脚注,上面计算的时区偏移量可能与以下看似等效的表达式不同,这可能是由于夏令时规则的变化:

 offset = datetime.fromtimestamp(0) - datetime.utcfromtimestamp(0) # NO!

更新: 此代码段存在使用当前时间的 UTC 偏移量的弱点,这可能与输入日期时间的 UTC 偏移量不同。请参阅对此答案的评论以获取另一种解决方案。

要绕过不同的时间,请从传入的时间中获取纪元时间。这是我所做的:

 def utc2local(utc):
    epoch = time.mktime(utc.timetuple())
    offset = datetime.fromtimestamp(epoch) - datetime.utcfromtimestamp(epoch)
    return utc + offset

原文由 David Foster 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题