How to make an unaware datetime timezone aware in python
我需要做的是
我有一个TimeZone Unknowled DateTime对象,我需要在其中添加一个时区,以便能够将其与其他TimeZone-Aknowled DateTime对象进行比较。我不想将我的整个应用程序转换为不知道这个遗留案例的时区。
我试过什么
首先,要演示问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type"help","copyright","credits" or"license" for more information. >>> import datetime >>> import pytz >>> unaware = datetime.datetime(2011,8,15,8,15,12,0) >>> unaware datetime.datetime(2011, 8, 15, 8, 15, 12) >>> aware = datetime.datetime(2011,8,15,8,15,12,0,pytz.UTC) >>> aware datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>) >>> aware == unaware Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: can't compare offset-naive and offset-aware datetimes |
首先,我尝试了Astimezone:
1 2 3 4 5 | >>> unaware.astimezone(pytz.UTC) Traceback (most recent call last): File"<stdin>", line 1, in <module> ValueError: astimezone() cannot be applied to a naive datetime >>> |
这一次失败并不奇怪,因为它实际上是在试图进行转换。替换似乎是一个更好的选择(根据python:如何获取datetime.today()的值,它是"时区感知的"?):
1 2 3 4 5 6 7 | >>> unaware.replace(tzinfo=pytz.UTC) datetime.datetime(2011, 8, 15, 8, 15, 12, tzinfo=<UTC>) >>> unaware == aware Traceback (most recent call last): File"<stdin>", line 1, in <module> TypeError: can't compare offset-naive and offset-aware datetimes >>> |
但正如您所看到的,replace似乎设置了TZINFO,但并没有使对象意识到。我准备在分析输入字符串之前修改它,使其具有时区(如果这很重要的话,我使用dateutil进行分析),但这看起来非常笨拙。
另外,我在python 2.6和python 2.7中都尝试过这种方法,得到了相同的结果。
语境
我正在为一些数据文件编写解析器。如果日期字符串没有时区指示器,我需要支持一种旧格式。我已经修复了数据源,但仍然需要支持旧数据格式。由于各种业务BS原因,一次性转换遗留数据不是一个选项。一般来说,我不喜欢硬编码默认时区的想法,在这种情况下,这似乎是最好的选择。我有合理的信心知道所有的遗留数据都是在UTC,所以我准备接受在这种情况下违约的风险。
在一般的天真,让感知使用DateTime时区:localize method,theP></
1 2 3 4 5 6 7 8 | import datetime import pytz unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0) aware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0, pytz.UTC) now_aware = pytz.utc.localize(unaware) assert aware == now_aware |
for the UTC时区is not necessary to,它真的不使用
1 | now_aware = unaware.replace(tzinfo=pytz.UTC) |
工厂。(
所有这些所谓的外部使用一模一样,但结果是你可以使用as the datetime模块也只是给我,这个答案:P></
1 2 3 4 5 6 7 8 | from datetime import datetime from datetime import timezone dt = datetime.now() dt.replace(tzinfo=timezone.utc) print(dt.replace(tzinfo=timezone.utc).isoformat()) '2017-01-12T22:11:31+00:00' |
不pytz fewer限制和问题。P></
注意:如果你使用this with python3愿望和python2,你可以使用this as for the进出口井的时区(UTC):硬编码)P></
1 2 3 4 5 6 7 8 9 10 11 12 13 | try: from datetime import timezone utc = timezone.utc except ImportError: #Hi there python2 user class UTC(tzinfo): def utcoffset(self, dt): return timedelta(0) def tzname(self, dt): return"UTC" def dst(self, dt): return timedelta(0) utc = UTC() |
我使用_ DT DT从感知到_ toP></
1 | dt_unaware = dt_aware.replace(tzinfo=None) |
和感知到的_ _ DT DTP></
1 2 3 | from pytz import timezone localtz = timezone('Europe/Lisbon') dt_aware = localtz.localize(dt_unware) |
but is also a答案之前良好的解决方案。P></
在使用Django的this statement to convert to安安unaware感知时间:P></
1 2 3 | from django.utils import timezone dt_aware = timezone.make_aware(dt_unaware, timezone.get_current_timezone()) |
结果同意与以前的答案是,如果你是好的结束和开始在UTC。但我也认为它是普通人在换工作情景感知价值与TZ that has a that has a local DateTime不是UTC时区。P></
如果你是去到一个名字,可能会infer replace()will be the right和感知产生适用的DateTime对象。this is not the房屋。P></
(tzinfo=replace the…)在ITS的行为似乎是随机的。它是therefore useless。我不使用这个!P></
localize is the correct函数的使用。实例:P></
1 | localdatetime_aware = tz.localize(datetime_nonaware) |
或更多的完整的实例:P></
1 2 3 | import pytz from datetime import datetime pytz.timezone('Australia/Melbourne').localize(datetime.now()) |
给我感知的DateTime值时区当地时间:of the currentP></
1 | datetime.datetime(2017, 11, 3, 7, 44, 51, 908574, tzinfo=<DstTzInfo 'Australia/Melbourne' AEDT+11:00:00 DST>) |
这codifies @ @ unutbu'塞尔吉奥和S的答案。它将与"只是工作"或者
1 2 3 4 5 6 7 8 | def make_tz_aware(dt, tz='UTC', is_dst=None): """Add timezone information to a datetime object, only if it is naive.""" tz = dt.tzinfo or tz try: tz = pytz.timezone(tz) except AttributeError: pass return tz.localize(dt, is_dst=is_dst) |
这似乎是
我知道purely二法P></
1 2 3 4 5 | from datetime import datetime import pytz naive = datetime.now() aware = naive.replace(tzinfo=pytz.UTC) |
前P></
1 | aware = pytz.UTC.localize(naive) |
当然你可以使用任何杂志,instead of UTC时区,P></
以本地时区(用add dateutil);P></
1 2 3 4 5 6 | from dateutil import tz import datetime dt_unaware = datetime.datetime(2017, 6, 24, 12, 24, 36) dt_aware = dt_unaware.replace(tzinfo=tz.tzlocal()) |
在回答unutbu' format of the s;自制的工具把手,事情是这样的句法,与更多的直觉。can be installed with皮普。P></
1 2 3 4 5 6 7 | import datetime import saturn unaware = datetime.datetime(2011, 8, 15, 8, 15, 12, 0) now_aware = saturn.fix_naive(unaware) now_aware_madrid = saturn.fix_naive(unaware, 'Europe/Madrid') |