当前位置: 首页 > 面试题库 >

pytz:仅从GMT偏移量返回Olson时区名称

华子航
2023-03-14
问题内容

我有一个遗留应用程序,我将需要补充一些数据。当前,我们有一个数据库表,用于存储美国(及其地区)邮政编码,GMT偏移量以及一个标志,用于显示该邮政编码是否使用夏时制。这是从某个免费提供商处下载的,我现在找不到源。

现在,我需要用America/New York每个邮政编码的完整奥尔森名称(例如)来补充此表,因为这似乎是将存储在数据库中的给定日期/时间(对于该购买者而言本地的)转换为UTC aware datetime对象的唯一好方法。

看一下桌子:

zip    state  city          lat      lon       gmt  dst 
00605  PR     AGUADILLA     18.4372  -67.1593  -4   f
02830  RI     HARRISVILLE   41.9782  -71.7679  -5   t
99503  AK     ANCHORAGE     61.1895  -149.874  -9   t

在另一个相关的表格中Purchases,我有一postres timestamp without tz列,当前包含类似的内容2014-05-27T15:54:26,它表示在该邮政编码上本地购买商品的时间。(忽略将这些本地化的时间戳保存到数据库时剥离时区信息的愚蠢性)

最大的问题是:

如何UTC time从该timestamp字符串为zipcode表格中的每个邮政编码创建规范化?这将假定时间戳记是在zipcode表中每个示例行的本地写入到DB的。

例如,手动查找示例表中每个项目的Olson时区名称,我得出以下结果:

>>> timestring = '2014-05-27T15:54:26'
>>> dt_naive = datetime.strptime(timestring, '%Y-%m-%dT%H:%M:%S')

>>> # First example - Puerto Rico (no DST since 1945)
>>> print pytz.utc.normalize(pytz.timezone('America/Puerto_Rico').localize(dt_naive))
2014-05-27 19:54:26+00:00

# Second example - Road Island (At that timestamp, UTC Offset was same as PR because of DST)
>>> print pytz.utc.normalize(pytz.timezone('US/Eastern').localize(dt_naive))
>>> 2014-05-27 19:54:26+00:00

# Third Example - Anchorage, AK (AKDT at timestamp)
>>> print pytz.utc.normalize(pytz.timezone('America/Anchorage').localize(dt_naive))
2014-05-27 23:54:26+00:00

我看过几种出售邮政编码数据库的商业产品,这些数据库可以给我一个邮政编码->时区查询。但是,他们似乎只给我给定时区的“
EST”。因此,我认为我可以将美国时区(包括地区)的可能时区列表映射到每个时区的奥尔森名称。可能看起来像这样:

zipcode_olson_lookup = {
    ('PR', 'f', 'AST'): 'America/Puerto_Rico',
    ('AK', 'f', 'AKDT',): 'America/Anchorage',
    ('AK', 't', 'AKT',): 'America/Anchorage',
    ...
}

任何建议都非常欢迎!


问题答案:

UTC本身的偏移量可能是不明确的(它可能对应于在某个时间段内可能具有不同规则的多个时区):

#!/usr/bin/env python
from datetime import datetime, timedelta
import pytz # $ pip install pytz

input_utc_offset = timedelta(hours=-4)
timezone_ids = set()
now = datetime.now(pytz.utc) #XXX: use date that corresponds to input_utc_offset instead!
for tz in map(pytz.timezone, pytz.all_timezones_set):
    dt = now.astimezone(tz)    
    tzinfos = getattr(tz, '_tzinfos',
                      [(dt.tzname(), dt.dst(), dt.utcoffset())])        
    if any(utc_offset == input_utc_offset for utc_offset, _, _ in tzinfos):
        # match timezones that have/had/will have the same utc offset 
        timezone_ids.add(tz.zone)
print(timezone_ids)

输出量

{'America/Anguilla',
 'America/Antigua',
 'America/Argentina/Buenos_Aires',
 ...,
 'Cuba',
 'EST5EDT',
 'Jamaica',
 'US/East-Indiana',
 'US/Eastern',
 'US/Michigan'}

您甚至不能使用限制列表,pytz.country_timezones['us']因为它会排除您的示例之一:'America/Puerto_Rico'

如果您知道坐标(纬度,经度);您可以从shape文件中获取时区ID
:您可以使用本地数据库或网络服务:

#!/usr/bin/env python
from geopy import geocoders # pip install "geopy[timezone]"

g = geocoders.GoogleV3()
for coords in [(18.4372,  -67.159), (41.9782,  -71.7679), (61.1895,  -149.874)]:
    print(g.timezone(coords).zone)

输出量

America/Puerto_Rico
America/New_York
America/Anchorage

注意:某些当地时间可能是模棱两可的,例如,在DST转换结束时时间回落。在这种情况下,您可以传递is_dst=None.localize()方法来引发异常。

tz数据库的不同版本在某些日期的某些时区可能具有不同的utc偏移,即,仅存储UTC时间和时区ID(使用哪种版本取决于您的应用程序)是不够的。



 类似资料:
  • oracle DB是否能够返回时区区域,例如欧洲/伦敦,而不仅仅是偏移?我想知道服务器所在的地区名称。 从DUAL中选择SYSTIMESTAMP参数;返回日期、时间和偏移量: 从dual中选择DBTIMEZONE;返回偏移量:

  • 问题内容: 是否可以跳过X个第一行,并在一个查询中选择所有其他行?像那样: 它将选择:pqr,stu,vwx,yz 我尝试使用LIMIT和OFFSET完成此操作,但是问题是表是动态的,而且我不知道应该输入哪个LIMIT(我不知道表中有多少行)。 问题答案: 如果只需要最后N行,请尝试以下操作: 这会根据的顺序为您提供最后几条记录。 您可以使用自动递增的主键(希望有一个主键)来确定行的顺序(如果无法

  • 问题内容: 我需要以[+/-] hh:mm的格式保存手机的时区 我正在使用TimeZone类来处理此问题,但是我只能获得以下格式: 我宁愿不对结果进行子串化,是否可以设置任何键或选项标志来仅获取值,而不获取该时区的名称(GMT / CET / PST …)? 问题答案: 我需要以[+/-] hh:mm的格式保存手机的时区 不,你没有。仅靠偏移量是不够的,您需要存储整个时区名称/ id。例如,我住在

  • 问题内容: 我知道相反。给定一个时区,我可以通过以下代码片段获取时区偏移量: 我想知道如何从时区偏移量获取时区名称。 鉴于 (以毫秒为单位; +6.00偏移) 我想得到以下任何可能的时区名称的结果: 问题答案: 用

  • 问题内容: 由于某些原因,我无法从以下代码中找出原因: 我得到: 我认为,什么时候可以得到: …因为我不认为我的时区距离UTC 6小时9分钟。 我已经查看了源代码,但是我承认我还不能完全弄清楚出了什么问题。 我已经将其他值传递给该函数,并且它返回的值似乎是正确的。但是由于某种原因,与我的时区有关的信息不正确。 最后,我旁边的多维数据集中的同事已确认该函数在其计算机上返回了正确的时区信息。 有谁知道

  • 问题内容: 如何获得与C 调用给出的值相对应的Olson时区名称(例如)? 这是通过,通过符号链接或在与时间相关的系统配置文件中设置变量来覆盖的值。 问题答案: 我认为最好的选择是遍历所有pytz时区,并检查哪个匹配本地时区,每个pytz时区对象都包含有关utcoffset和tzname的信息,例如CDT,EST,可以从和获取有关本地时间的相同信息,我认为这是足以正确匹配pytz数据库中的本地时区