简体   繁体   English

通过UTC偏移和DST位使Datetime时区可识别

[英]Make Datetime Timezone Aware From UTC Offset and DST Bit

I am currently battling the cruel beast that is timezone localization in my django application, and having some trouble... I want to make naive datetimes timezone aware, based on a location. 我目前正在与Django应用程序中的时区本地化这个残酷的野兽作战,并遇到了一些麻烦...我想根据位置使天真的datetimes时区知道。 I have a database of zip codes that have the UTC offset in hours, as well as a 0 or 1 depending on if the zip codes adhere to DST. 我有一个邮政编码数据库,该数据库具有以小时为单位的UTC偏移量,以及0或1,具体取决于邮政编码是否符合DST。 How might I use this data to accurately apply a timezone to my datetimes? 如何使用这些数据将时区准确地应用于日期时间? Ideally the datetime would respond to changes in DST, rather than just always simply following the UTC offset. 理想情况下,日期时间将响应DST的变化,而不是始终仅遵循UTC偏移量。

With pytz it's not hard to convert the datetimes as you describe; 使用pytz,您可以轻松转换日期时间。 the only complication is getting tzinfo instances corresponding to the time zone descriptions in your database. 唯一的麻烦就是获取与数据库中的时区描述相对应的tzinfo实例。

The problem is that real timezones are more complicated than just offset + DST. 问题在于实时时区比仅偏移+ DST更复杂。 For example, different regions adopted DST at different points in history, and different regions in the world can make the DST switch at different points in the year. 例如,不同地区在历史上的不同时间点采用DST,而世界上不同的地区可以在一年中的不同时间点进行DST切换。

If your usage is only for the US, and only concerns future (not historical) dates, then there are a couple options that should yield accurate results (though note the caveat below): 如果您的用法仅适用于美国,并且仅涉及未来(而不是历史)日期,那么有几个选项应该会产生准确的结果(尽管请注意以下警告):

  1. Just create your own concrete tzinfo subclass that uses the offset and DST flag from your database. 只需创建自己的具体tzinfo子类即可,该子类使用数据库中的offset和DST标志。 For example, the Python documentation gives sample code for "a complete implementation of current DST rules for major US time zones." 例如, Python文档提供了“针对美国主要时区的当前DST规则的完整实现”的示例代码。

  2. Map from the offset / DST to the corresponding pytz tzinfo object. 从偏移量/ DST映射到相应的pytz tzinfo对象。 Since there are only a handful of possible combinations in the US, just figure out which timezone name corresponds and use that. 由于在美国只有少数几种可能的组合,因此只需找出对应的时区名称并使用即可。

     TZ_MAP = { ... (-5, 1): pytz.timezone('US/Eastern') ... } tz = TZ_MAP[(offset, is_dst)] 

Once you have the tzinfo instance the conversion is simple, but note that dealing with DST involves inherent ambiguities. 一旦有了tzinfo实例,转换就很简单,但是请注意,处理DST涉及固有的歧义。 For example, when the clock is turned back at 2am, all the times between 1am and 2am occur twice in the local timezone. 例如,当时钟在凌晨2点调回时,凌晨1点到凌晨2点之间的所有时间在本地时区中都会出现两次。 Assuming you don't know which one you actually mean, you can either pick one arbitrarily, or raise an exception. 假设您不知道真正的意思,则可以随意选择一个,也可以提出例外。

# with no is_dst argument, pytz will guess if there is ambiguity
aware_dt = tz.localize(naive_dst)

# with is_dst=None, pytz will raise an exception if there is ambiguity
aware_dt = tz.localize(naive_dst, is_dst=None)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM