【发布时间】:2016-08-06 01:08:36
【问题描述】:
在 Python 中,假设我的日期是 2016 年 12 月 25 日。如何在该日期创建一个可识别时区的日期时间?
如果它与 Django 的时区处理兼容,则可以加分。
【问题讨论】:
-
这专门用于从日期获取日期时间,而不是从预先存在的幼稚日期时间。
-
您可以通过
combine与time(0, 0)来获得天真的日期时间
在 Python 中,假设我的日期是 2016 年 12 月 25 日。如何在该日期创建一个可识别时区的日期时间?
如果它与 Django 的时区处理兼容,则可以加分。
【问题讨论】:
combine 与time(0, 0) 来获得天真的日期时间
诀窍是先将combine 天真的时间和日期转换成天真的日期时间。然后可以将这个幼稚的日期时间转换为有意识的日期时间。
可以使用第三方包pytz(在本例中使用“欧洲/伦敦”时区)完成转换:
import datetime
import pytz
naive_time = datetime.time(0, 30)
date = datetime.date(2016, 12, 25)
naive_datetime = datetime.datetime.combine(date, naive_time)
timezone = pytz.timezone('Europe/London')
aware_datetime = timezone.localize(naive_datetime)
如果您在 Django 中执行此操作,并且想要使用当前时区(在 Django 中配置),您可以将最后两行替换为对 make_aware 的调用:
from django.utils import timezone
aware_datetime = timezone.make_aware(naive_datetime)
【讨论】:
.localize() method for timezones with a non-fixed utc offset。或django.utils.timezone.make_aware().
date_object.replace(tzinfo=timezone.get_current_timezone())
replace() 是问题的根源!正如 jfs 所说,请改用 localize()。 replace() 在转换时区时不考虑日期,因此当时区发生转换时会出现问题,例如夏令时(或其他转换......请参阅here)
datetime.combine() 在处理时区时没有考虑日期,导致结果不正确。正如 jfs 所说,请改用timezone.localize()!更具体地说,使用无时区的 combine,然后使用 localize。
Erik 对this question 的回答解释了为什么您应该使用datetime.combine() 后跟timezone.localize()。直接在 datetime.time 实例上设置时区不会考虑日期,这可能会给您留下不正确的结果(由于夏令时甚至历史转换)。 datetime.combine() 没那么聪明!
>>> import pytz
>>> import datetime
>>> d = datetime.date(2016, 12, 25)
>>> t = datetime.time(12)
>>> tz = pytz.timezone('US/Pacific')
>>> tz.localize(datetime.datetime.combine(d,t))
datetime.datetime(2016, 12, 25, 12, 0, tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>)
【讨论】: