【问题标题】:Get list of time zones with time difference from GMT获取与 GMT 时差的时区列表
【发布时间】:2019-10-14 02:40:27
【问题描述】:

我有一个 Django 应用程序,并且有一个硬编码的时区列表。我知道pytz 可用于获取所有时区的列表。但它没有显示它们相对于 GMT 的时差。请建议如何获得这样的列表。

TIMEZONE_CHOICES = (
    ("<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>", "<DstTzInfo 'Africa/Abidjan' LMT-1 day, 23:44:00 STD>"),
    ("<DstTzInfo 'Africa/Accra' LMT-1 day, 23:59:00 STD>", "<DstTzInfo 'Africa/Accra' LMT-1 day, 23:59:00 STD>"),
    ("<DstTzInfo 'Africa/Addis_Ababa' LMT+2:27:00 STD>", "<DstTzInfo 'Africa/Addis_Ababa' LMT+2:27:00 STD>"),
    ("<DstTzInfo 'Africa/Algiers' LMT+0:12:00 STD>", "<DstTzInfo 'Africa/Algiers' LMT+0:12:00 STD>"),
    ("<DstTzInfo 'Africa/Asmara' LMT+2:27:00 STD>", "<DstTzInfo 'Africa/Asmara' LMT+2:27:00 STD>"),...)

【问题讨论】:

    标签: python python-3.x timezone pytz django-1.11


    【解决方案1】:

    假设与 UTC 的时差是 GMT 的可接受替代方案(UTC 和 GMT 几乎但不完全相同),您可以从 pytz.timezone 对象获取时区偏移和相关信息。

    对于具有多个偏移量的时区(由于夏令时、历史变化等),您可以从_tzinfos 属性中获取相关的时区和偏移量。对于具有单个偏移量的时区,您可以从 _utcoffset 属性中获取偏移量。

    以下示例创建一个字典,其中pytz.all_timezones 中的每个时区是一个键,值是一个包含相关区域和偏移信息的元组列表。

    from pytz import all_timezones, timezone
    
    timezones = {}
    for tz in all_timezones:
        tzinfos = getattr(timezone(tz), '_tzinfos', None)
        if tzinfos:
            timezones[tz] = [(zone, str(offset)) for offset, dst, zone in tzinfos]
        else:
            timezones[tz] = [(tz, str(timezone(tz)._utcoffset))]
    
    print(timezones)
    # {
    #     'Africa/Abidjan': [('LMT', '-1 day, 23:44:00'), ('GMT', '0:00:00')],
    #     'Africa/Accra': [('LMT', '-1 day, 23:59:00'), ('GMT', '0:00:00'), ('+0020', '0:20:00')],
    #     'Africa/Addis_Ababa': [('LMT', '2:27:00'), ('EAT', '3:00:00'), ('+0230', '2:30:00'), ('+0245', '2:45:00')],
    #     'Africa/Algiers': [('LMT', '0:12:00'), ('PMT', '0:09:00'), ('WET', '0:00:00'), ('WEST', '1:00:00'), ('CET', '1:00:00'), ('CEST', '2:00:00')],
    #     'Africa/Asmara': [('LMT', '2:27:00'), ('EAT', '3:00:00'), ('+0230', '2:30:00'), ('+0245', '2:45:00')],
    #     ...
    #     }
    

    如果您更喜欢每个区域的信息以字符串形式连接的列表(如您的示例),那么您可以进行如下修改。

    timezones = []
    for tz in all_timezones:
        tzinfos = getattr(timezone(tz), '_tzinfos', None)
        if tzinfos:
            timezones.extend([' '.join([tz, zone, str(offset)]) for offset, dst, zone in tzinfos])
        else:
            timezones.append(' '.join([tz, str(timezone(tz)._utcoffset)]))
    

    根据您关于删除偏移量不落在输出中的四分之一小时间隔某处的时区的评论,您可能希望删除包含在历史日期(通常是 19 世纪和 20 世纪初的日期)的各种时区) 其中大部分都包含在某种“平均时间”变体中,例如“本地平均时间”的“LMT”。删除这些的一种蛮力方法就是过滤掉所有以“MT”结尾的时区缩写,“GMT”除外。目前使用中可能还有其他一些我不知道的例外情况,但也应该以与“GMT”相同的方式处理。

    timezones = {}
    for tz in all_timezones:
        tzinfos = getattr(timezone(tz), '_tzinfos', None)
        if tzinfos:
            timezones[tz] = [(zone, str(offset)) for offset, dst, zone in tzinfos if zone == 'GMT' or not zone.endswith('MT')]
        else:
            timezones[tz] = [(tz, str(timezone(tz)._utcoffset))]
    
    print(timezones)
    # {
    #     'Africa/Abidjan': [('GMT', '0:00:00')],
    #     'Africa/Accra': [('GMT', '0:00:00'), ('+0020', '0:20:00')],
    #     'Africa/Addis_Ababa': [('EAT', '3:00:00'), ('+0230', '2:30:00'), ('+0245', '2:45:00')],
    #     'Africa/Algiers': [('WET', '0:00:00'), ('WEST', '1:00:00'), ('CET', '1:00:00'), ('CEST', '2:00:00')],
    #     'Africa/Asmara': [('EAT', '3:00:00'), ('+0230', '2:30:00'), ('+0245', '2:45:00')],
    #     ...
    #     }
    

    【讨论】:

    • 我们可以从输出中删除分钟,如 44、14 等吗?因为时区差异通常像 15、30 和 45 分钟以及小时。
    • @SachinSingh - 您可能希望删除仅包含历史日期的具有异常偏移的时区。有关详细信息,请参阅答案编辑。
    猜你喜欢
    • 1970-01-01
    • 2022-11-25
    • 2010-09-18
    • 1970-01-01
    • 2019-04-06
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 2012-11-28
    相关资源
    最近更新 更多