У меня есть приложение 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>"),...)
Предполагая, что разница во времени с 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')],
# ...
# }
@SachinSingh - вы, вероятно, хотите удалить часовые пояса с необычными смещениями, которые включены только для исторических дат. Подробнее см. Редактирование ответа.
мы можем удалить минуты, такие как 44, 14 и т. д. из вывода? из-за разницы в часовых поясах, как правило, 15, 30 и 45 минут вместе с часом.