从格林尼治标准时间(GMT)获取具有时差的时区列表

时间:2019-05-28 14:25:28

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

我有一个Django应用程序,并且有一个硬编码的时区列表。我知道pytz可用于获取所有时区的列表。但这并未显示出它们相对于格林尼治标准时间的时差。请建议如何获取这样的列表。

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>"),...)

1 个答案:

答案 0 :(得分:1)

假设与UTC的时差可以替代GMT(UTC和GMT几乎但不完全相同),则可以从pytz.timezone对象获得时区偏移量和相关信息。

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

下面的示例创建一个dict,其中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')],
#     ...
#     }