使用Python将UTC datetime字符串转换为本地日期时间

我从来没有必要将时间转换为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”等等)?我确定我的第一个问题的答案可能包含第二个答案的参数。


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

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)


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

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例子中的时间问题。 埃里克·范奥斯滕的修正案中的时间问题较少。

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

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

请参阅tzinfo对象上的datetime文档。 你必须实现你想要支持自己的时区。 这些都是文档底部的例子。

这里有一个简单的例子:

from datetime import datetime,tzinfo,timedelta

class Zone(tzinfo):
    def __init__(self,offset,isdst,name):
        self.offset = offset
        self.isdst = isdst
        self.name = name
    def utcoffset(self, dt):
        return timedelta(hours=self.offset) + self.dst(dt)
    def dst(self, dt):
            return timedelta(hours=1) if self.isdst else timedelta(0)
    def tzname(self,dt):
         return self.name

GMT = Zone(0,False,'GMT')
EST = Zone(-5,False,'EST')

print datetime.utcnow().strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(GMT).strftime('%m/%d/%Y %H:%M:%S %Z')
print datetime.now(EST).strftime('%m/%d/%Y %H:%M:%S %Z')

t = datetime.strptime('2011-01-21 02:37:21','%Y-%m-%d %H:%M:%S')
t = t.replace(tzinfo=GMT)
print t
print t.astimezone(EST)

产量

01/22/2011 21:52:09 
01/22/2011 21:52:09 GMT
01/22/2011 16:52:09 EST
2011-01-21 02:37:21+00:00
2011-01-20 21:37:21-05:00a
链接地址: http://www.djcxy.com/p/46559.html

上一篇: Convert UTC datetime string to local datetime with Python

下一篇: Creating a DateTime in a specific Time Zone in c#