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

2024-04-26 09:23:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我从来没有把时间转换成UTC和UTC。最近有个请求让我的应用程序知道时区,我一直在绕圈子。关于将本地时间转换为UTC的许多信息,我发现这些信息相当基本(也许我也做得不对),但是我找不到任何关于将UTC时间轻松转换为最终用户时区的信息。

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

datetime.utcfromtimestamp(timestamp)

这似乎起作用了。当我的应用程序存储数据时,它将提前5小时存储(我是EST-5)

数据被存储在appengine的BigTable中,当检索到它时,它会显示为一个字符串,如下所示:

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

如何将此字符串转换为用户正确时区中的日期时间?

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


Tags: 数据字符串答案用户信息应用程序datetime时间
3条回答

请参阅有关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

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

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对象,请查看python-dateutil库。它在zoneinfo (Olson) database之上提供了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)

相关问题 更多 >