简体   繁体   中英

Get list of time zones with time difference from GMT

I have a Django application and I have a list of timezones hardcoded. I know pytz can be used to get a list of all timezones. But it does not show their time difference with respect to GMT. Please suggest how to get a list like this.

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

Assuming the time difference from UTC is an acceptable alternative to GMT (UTC and GMT are nearly but not exactly the same), you can get time zone offset and related information from the pytz.timezone object.

For time zones with multiple offsets (due to daylight savings, historical changes, etc), you can get the related zones and offsets from the _tzinfos attribute. For time zones with a single offset, you can get the offset from the _utcoffset attribute.

Following example creates a dict where each time zone in pytz.all_timezones is a key and the value is a list of tuples containing the related zone and offset information.

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')],
#     ...
#     }

If you prefer a list where the info for each zone is joined in a string (like your example), then you can modify as follows.

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)]))

Per your comment regarding removing time zones with offsets that do not fall somewhere on a quarter hour interval from the output, you are probably looking to remove the various time zones that are included for historical dates (often 19th and early 20th century dates) most of which are included as some sort of "Mean Time" variation like "LMT" for "Local Mean Time". One brute force approach to removing those is just to filter out all time zone abbreviations that end in "MT" with the exception of "GMT". There are probably a few other exceptions in current use that I am unaware of but should also be handled in the same way as "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')],
#     ...
#     }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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