Spec-Zone.ru › Django 1.9

Часовые пояса

Обзор

При включенном управлении часовыми поясами Django сохраняет информацию о датах и временах в формате UTC в базе данных, использует объекты datetime с учетом часового пояса во внутренних операциях и преобразует их для отображения в часовом поясе конечного пользователя в шаблонах и формах.

Это полезно, если ваши пользователи находятся в нескольких часовых поясах и вы хотите отображать информацию о датах и времени в соответствии с местным временем каждого пользователя.

Даже если ваш веб-сайт доступен только в одном часовом поясе, все равно рекомендуется хранить данные в формате UTC в вашей базе данных. Основная причина — летнее время (DST). Многие страны имеют систему DST, где время переводится вперёд весной и назад осенью. Если вы работаете с местным временем, вы, вероятно, столкнетесь с ошибками дважды в год, когда происходят переходы. (Документация pytz подробнее рассматривает эти проблемы.) Это, вероятно, не имеет значения для вашего блога, но это проблема, если вы переплачиваете или недоплачиваете своим клиентам на один час дважды в год, каждый год. Решение этой проблемы — использовать UTC в коде и использовать местное время только при взаимодействии с конечными пользователями.

Поддержка часовых поясов отключена по умолчанию. Чтобы включить её, задайте USE_TZ = True в вашем файле настроек. Установка pytz настоятельно рекомендуется, но может не быть обязательной в зависимости от конкретного бэкэнда базы данных, операционной системы и часового пояса. Если при запросе дат или времён возникает исключение, попробуйте установить её перед тем, как сообщать об ошибке. Это так же просто, как:

$ pip install pytz

Примечание

Файл по умолчанию settings.py созданный django-admin startproject включает USE_TZ = True для удобства.

Примечание

Также есть независимая, но связанная настройка USE_L10N, которая управляет тем, должен ли Django активировать локализацию форматов. Подробнее см. Локализация форматов.

Если вы столкнулись с конкретной проблемой, начните с часто задаваемых вопросов о часовых поясах.

Концепции

Обычные и осознанные объекты datetime

Объекты datetime.datetime Python имеют атрибут tzinfo, который может использоваться для хранения информации о часовом поясе, представленной как экземпляр подкласса datetime.tzinfo. Когда этот атрибут установлен и описывает смещение, объект datetime является осознанным. В противном случае он обычный.

Вы можете использовать is_aware() и is_naive(), чтобы определить, являются ли даты и время осознанными или обычными.

Когда поддержка часовых поясов отключена, Django использует обычные объекты datetime в местном времени. Это просто и достаточно для многих случаев использования. В этом режиме, чтобы получить текущее время, вы написали бы:

import datetime

now = datetime.datetime.now()

Когда поддержка часовых поясов включена (USE_TZ=True), Django использует осознанные объекты datetime с учетом часового пояса. Если ваш код создаёт объекты datetime, они также должны быть осознанными. В этом режиме пример выше становится:

from django.utils import timezone

now = timezone.now()

Предупреждение

Работа с осознанными объектами datetime не всегда интуитивна. Например, аргумент tzinfo стандартного конструктора datetime не работает надёжно для часовых поясов с DST. Использование UTC обычно безопасно; если вы используете другие часовые пояса, вы должны внимательно изучить документацию pytz.

Примечание

Объекты datetime.time Python также имеют атрибут tzinfo, а PostgreSQL имеет соответствующий тип time with time zone. Однако, как сказано в документации PostgreSQL, этот тип «обладает свойствами, которые приводят к сомнительной полезности».

Django поддерживает только обычные объекты времени и вызовет исключение, если вы попытаетесь сохранить осознанный объект времени, так как часовой пояс для времени без связанной даты не имеет смысла.

Интерпретация обычных объектов datetime

Когда USE_TZ True, Django по-прежнему принимает обычные объекты datetime, чтобы сохранить обратную совместимость. Когда слой базы данных получает такой объект, он пытается сделать его осознанным, интерпретируя его в по умолчанию часовом поясе и выводит предупреждение.

К сожалению, во время переходов на летнее/зимнее время некоторые даты и время не существуют или являются неоднозначными. В таких ситуациях pytz вызовет исключение. Другие реализации tzinfo, такие как местный часовой пояс, используемый в качестве резервного варианта, когда pytz не установлен, могут вызвать исключение или вернуть неточные результаты. Вот почему вы всегда должны создавать осознанные объекты datetime, когда включена поддержка часовых поясов.

На практике это редко является проблемой. Django предоставляет вам осознанные объекты datetime в моделях и формах, а в большинстве случаев новые объекты datetime создаются из существующих с помощью арифметики timedelta. Единственным объектом datetime, который часто создаётся в коде приложения, является текущее время, и timezone.now() автоматически делает всё правильно.

По умолчанию часовой пояс и текущий часовой пояс

По умолчанию часовой пояс — это часовой пояс, определённый настройкой TIME_ZONE.

Текущий часовой пояс — это часовой пояс, используемый для отображения.

Вы должны установить текущий часовой пояс на фактический часовой пояс конечного пользователя с помощью activate(). В противном случае используется часовой пояс по умолчанию.

Примечание

Как объяснено в документации TIME_ZONE, Django устанавливает переменные среды, чтобы его процесс выполнялся в часовом поясе по умолчанию. Это происходит независимо от значения USE_TZ и текущего часового пояса.

Когда USE_TZ True, это полезно для сохранения обратной совместимости с приложениями, которые всё ещё полагаются на местное время. Однако, как объяснялось выше, это не совсем надёжно, и вы всегда должны работать с осознанными датами и временем в UTC в своём коде. Например, используйте utcfromtimestamp() вместо fromtimestamp() — и не забудьте установить tzinfo на utc.

Выбор текущего часового пояса

Текущий часовой пояс эквивалентен текущему языковому параметру для переводов. Однако нет аналога заголовка HTTP Accept-Language, который Django мог бы использовать для автоматического определения часового пояса пользователя. Вместо этого Django предоставляет функции выбора часовых поясов. Используйте их, чтобы построить логику выбора часового пояса, которая имеет смысл для вас.

Большинство веб-сайтов, которые учитывают часовые пояса, просто спрашивают пользователей, в каком часовом поясе они живут, и хранят эту информацию в профиле пользователя. Для анонимных пользователей они используют часовой пояс своей основной аудитории или UTC. pytz предоставляет помощники, такие как список часовых поясов по странам, которые вы можете использовать для предварительного выбора наиболее вероятных вариантов.

Вот пример, который сохраняет текущий часовой пояс в сессии. (Он полностью пропускает обработку ошибок ради простоты.)

Добавьте следующий middleware в MIDDLEWARE_CLASSES:

import pytz

from django.utils import timezone

class TimezoneMiddleware(object):
    def process_request(self, request):
        tzname = request.session.get('django_timezone')
        if tzname:
            timezone.activate(pytz.timezone(tzname))
        else:
            timezone.deactivate()

Создайте представление, которое может установить текущий часовой пояс:

from django.shortcuts import redirect, render

def set_timezone(request):
    if request.method == 'POST':
        request.session['django_timezone'] = request.POST['timezone']
        return redirect('/')
    else:
        return render(request, 'template.html', {'timezones': pytz.common_timezones})

Включите форму в template.html, которая будет POST в это представление:

{% load tz %}
{% get_current_timezone as TIME_ZONE %}
<form action="{% url 'set_timezone' %}" method="POST">
    {% csrf_token %}
    <label for="timezone">Time zone:</label>
    <select name="timezone">
        {% for tz in timezones %}
        <option value="{{ tz }}"{% if tz == TIME_ZONE %} selected="selected"{% endif %}>{{ tz }}</option>
        {% endfor %}
    </select>
    <input type="submit" value="Set" />
</form>

Часовые пояса в формах

При включении поддержки часовых поясов Django интерпретирует даты и время, введённые в формах, в текущем часовом поясе и возвращает осознанные объекты datetime в cleaned_data.

Если текущая временная зона вызывает исключение для дат и времени, которые не существуют или являются неоднозначными из-за перехода на летнее/зимнее время (временные зоны, предоставляемые pytz, делают это), такие даты и время будут отображаться как недопустимые значения.

Временные зоны в шаблонах

При включении поддержки временных зон Django преобразует объекты datetime с учетом временной зоны в текущую временную зону при их отображении в шаблонах. Это очень похоже на локализацию формата.

Предупреждение

Django не преобразует объекты datetime без учета временной зоны, потому что они могут быть неоднозначными, и потому что ваш код никогда не должен создавать объекты datetime без учета временной зоны, когда включена поддержка временных зон. Однако вы можете принудительно выполнить преобразование с помощью фильтров шаблонов, описанных ниже.

Преобразование в местное время не всегда уместно — вы можете генерировать вывод для компьютеров, а не для людей. Следующие фильтры и теги, предоставляемые библиотекой шаблонов tz, позволяют управлять преобразованиями временных зон.

Теги шаблонов

localtime

Включает или выключает преобразование объектов datetime с учетом временной зоны в текущую временную зону в содержащемся блоке.

Этот тег имеет точно такие же эффекты, что и настройка USE_TZ с точки зрения движка шаблонов. Это позволяет более точно управлять преобразованием.

Для активации или деактивации преобразования для блока шаблона используйте:

{% load tz %}

{% localtime on %}
    {{ value }}
{% endlocaltime %}

{% localtime off %}
    {{ value }}
{% endlocaltime %}

Примечание

Значение USE_TZ не учитывается внутри блока {% localtime %}.

timezone

Устанавливает или сбрасывает текущую временную зону в содержащемся блоке. Когда текущая временная зона сброшена, применяется значение по умолчанию.

{% load tz %}

{% timezone "Europe/Paris" %}
    Paris time: {{ value }}
{% endtimezone %}

{% timezone None %}
    Server time: {{ value }}
{% endtimezone %}

get_current_timezone

Вы можете получить имя текущей временной зоны, используя тег get_current_timezone:

{% get_current_timezone as TIME_ZONE %}

В качестве альтернативы, вы можете активировать процессор контекста tz() и использовать переменную контекста TIME_ZONE.

Фильтры шаблонов

Эти фильтры принимают как объекты datetime с учетом временной зоны, так и без учета. Для целей преобразования они предполагают, что объекты datetime без учета временной зоны находятся в временной зоне по умолчанию. Они всегда возвращают объекты datetime с учетом временной зоны.

localtime

Принудительно преобразует одно значение в текущую временную зону.

Например:

{% load tz %}

{{ value|localtime }}

utc

Принудительно преобразует одно значение в UTC.

Например:

{% load tz %}

{{ value|utc }}

timezone

Принудительно преобразует одно значение в произвольную временную зону.

Аргумент должен быть экземпляром подкласса tzinfo или именем временной зоны. Если это имя временной зоны, требуется pytz.

Например:

{% load tz %}

{{ value|timezone:"Europe/Paris" }}

Руководство по миграции временных зон

Вот как мигрировать проект, который был запущен до того, как Django поддерживал временные зоны.

База данных

PostgreSQL

База данных PostgreSQL хранит даты и время как timestamp with time zone. На практике это означает, что она преобразует даты и время из временной зоны подключения в UTC при сохранении и из UTC во временную зону подключения при извлечении.

Вследствие этого, если вы используете PostgreSQL, вы можете свободно переключаться между USE_TZ = False и USE_TZ = True. Временная зона подключения к базе данных будет установлена на TIME_ZONE или UTC соответственно, чтобы Django во всех случаях получал правильные даты и время. Вам не нужно выполнять какие-либо преобразования данных.

Другие базы данных

Другие бэкэнды хранят даты и время без информации о временной зоне. Если вы переключаетесь с USE_TZ = False на USE_TZ = True, вы должны преобразовать свои данные из местного времени в UTC — что не является детерминированным, если в вашем местном времени есть переход на летнее/зимнее время.

Код

Первый шаг — добавить USE_TZ = True в ваш файл настроек и установить pytz (если это возможно). На этом этапе все должно работать в основном. Если вы создаете объекты datetime без учета временной зоны в своем коде, Django делает их осознанными при необходимости.

Однако эти преобразования могут завершиться неудачно во время перехода на летнее/зимнее время, что означает, что вы еще не получаете всех преимуществ поддержки временных зон. Также вы, вероятно, столкнетесь с некоторыми проблемами, потому что невозможно сравнить объект datetime без учета временной зоны с объектом datetime с учетом временной зоны. Поскольку Django теперь предоставляет вам объекты datetime с учетом временной зоны, вы получите исключения всякий раз, когда сравниваете объект datetime, полученный из модели или формы, с объектом datetime без учета временной зоны, который вы создали в своем коде.

Поэтому второй шаг заключается в переработке вашего кода, где вы инициализируете объекты datetime, чтобы сделать их осознанными. Это можно сделать постепенно. django.utils.timezone определяет некоторые удобные вспомогательные функции для кода совместимости: now(), is_aware(), is_naive(), make_aware() и make_naive().

Наконец, для того, чтобы помочь вам найти код, который нуждается в обновлении, Django выводит предупреждение, когда вы пытаетесь сохранить объект datetime без учета временной зоны в базу данных:

RuntimeWarning: DateTimeField ModelName.field_name received a naive
datetime (2012-01-01 00:00:00) while time zone support is active.

Во время разработки вы можете преобразовать такие предупреждения в исключения и получить трассировку стека, добавив следующее в свой файл настроек:

import warnings
warnings.filterwarnings(
    'error', r"DateTimeField .* received a naive datetime",
    RuntimeWarning, r'django\.db\.models\.fields',
)

Файлы фикстур

При сериализации объекта datetime с учетом временной зоны включается смещение UTC, как в этом примере:

"2011-09-01T13:20:30+03:00"

Для объекта datetime без учета временной зоны этого, очевидно, нет:

"2011-09-01T13:20:30"

Для моделей с полями DateTimeField это различие делает невозможным создание фикстуры, которая работает как с, так и без поддержки временных зон.

Файлы фикстур, сгенерированные с помощью USE_TZ = False, или до Django 1.4, используют формат «без учета временной зоны». Если ваш проект содержит такие файлы фикстур, после включения поддержки временных зон вы увидите предупреждения RuntimeWarning при их загрузке. Чтобы избавиться от предупреждений, вы должны преобразовать свои файлы фикстур в формат «с учетом временной зоны».

Вы можете перегенерировать файлы фикстур с помощью loaddata и затем dumpdata. Или, если они достаточно небольшие, вы можете просто отредактировать их, добавив смещение UTC, которое соответствует вашей настройке TIME_ZONE в каждую сериализованную дату и время.

Вопросы и ответы

Настройка

  1. Мне не нужны несколько часовых поясов. Нужно ли включить поддержку часовых поясов?

    Да. При включенной поддержке часовых поясов Django использует более точную модель местного времени. Это защищает вас от тонких и невоспроизводимых ошибок, связанных с переходом на летнее время (DST).

    В этом отношении часовые пояса сопоставимы с unicode в Python. Сначала это сложно. Возникают ошибки кодирования и декодирования. Затем вы изучаете правила. И некоторые проблемы исчезают – вы больше никогда не получите искаженный вывод, когда ваше приложение получает входные данные, не являющиеся ASCII.

    При включении поддержки часовых поясов вы столкнетесь с некоторыми ошибками, потому что вы используете неявные даты и время, тогда как Django ожидает явных дат и времени. Такие ошибки появляются при выполнении тестов, и их легко исправить. Вы быстро научитесь избегать недопустимых операций.

    С другой стороны, ошибки, вызванные отсутствием поддержки часовых поясов, гораздо сложнее предотвратить, диагностировать и исправить. Любой процесс, связанный с запланированными задачами или арифметикой дат и времени, может привести к тонким ошибкам, которые будут беспокоить вас только один или два раза в год.

    По этим причинам поддержка часовых поясов включена по умолчанию в новых проектах, и вы должны её сохранять, если у вас нет веских причин для её отключения.

  2. Я включил поддержку часовых поясов. Я в безопасности?

    Возможно. Вы лучше защищены от ошибок, связанных с переходом на летнее время, но вы всё ещё можете навредить себе, бездумно преобразуя неявные даты и время в явные и наоборот.

    Если ваше приложение подключается к другим системам – например, если оно запрашивает веб-сервис – убедитесь, что даты и время указаны должным образом. Для безопасной передачи дат и времени их представление должно включать смещение UTC или их значения должны быть в UTC (или оба!).

    Наконец, наша система календаря содержит интересные ловушки для компьютеров:

    >>> import datetime
    >>> def one_year_before(value):       # DON'T DO THAT!
    ...     return value.replace(year=value.year - 1)
    >>> one_year_before(datetime.datetime(2012, 3, 1, 10, 0))
    datetime.datetime(2011, 3, 1, 10, 0)
    >>> one_year_before(datetime.datetime(2012, 2, 29, 10, 0))
    Traceback (most recent call last):
    ...
    ValueError: day is out of range for month
    

    (Чтобы реализовать эту функцию, вы должны решить, является ли 2012-02-29 минус один год 2011-02-28 или 2011-03-01, что зависит от ваших бизнес-требований.)

  3. Нужно ли устанавливать pytz?

    Да. Django придерживается политики не требовать внешних зависимостей, и по этой причине pytz является необязательным. Однако, установить его гораздо безопаснее.

    Как только вы активируете поддержку часовых поясов, Django нуждается в определении часового пояса по умолчанию. Если pytz доступен, Django загружает это определение из базы данных часовых поясов. Это наиболее точное решение. В противном случае, он полагается на разницу между местным временем и UTC, как сообщается операционной системой, для вычисления преобразований. Это менее надёжно, особенно во время перехода на летнее время.

    Кроме того, если вы хотите поддерживать пользователей в нескольких часовых поясах, pytz является эталоном для определений часовых поясов.

  4. Как взаимодействовать с базой данных, которая хранит даты и время в местном времени?

    Установите опцию TIME_ZONE в соответствующий часовой пояс для этой базы данных в настройке DATABASES.

    Это полезно для подключения к базе данных, которая не поддерживает часовые пояса и не управляется Django, когда USE_TZ значением True.

Решение проблем

  1. Моё приложение завершается с ошибкой TypeError: can't compare offset-naive and offset-aware datetimes – в чём проблема?

    Давайте воспроизведём эту ошибку, сравнив неявную и явную дату и время:

    >>> import datetime
    >>> from django.utils import timezone
    >>> naive = datetime.datetime.utcnow()
    >>> aware = timezone.now()
    >>> naive == aware
    Traceback (most recent call last):
    ...
    TypeError: can't compare offset-naive and offset-aware datetimes
    

    Если вы столкнулись с этой ошибкой, скорее всего, ваш код сравнивает эти два объекта:

    • дата и время, предоставленные Django – например, значение, считанное с формы или поля модели. Поскольку вы включили поддержку часовых поясов, она является явной.
    • дата и время, сгенерированные вашим кодом, которые являются неявными (иначе вы бы этого не читали).

    В общем случае правильное решение заключается в изменении вашего кода для использования явной даты и времени.

    Если вы пишете подключаемое приложение, которое должно работать независимо от значения USE_TZ, вы можете найти функцию django.utils.timezone.now() полезной. Эта функция возвращает текущую дату и время в виде неявной даты и времени, когда USE_TZ = False и как явной даты и времени, когда USE_TZ = True. Вы можете добавить или вычесть datetime.timedelta по мере необходимости.

  2. Я вижу много RuntimeWarning: DateTimeField received a naive datetime (YYYY-MM-DD HH:MM:SS) while time zone support is active – это плохо?

    Когда поддержка часовых поясов включена, слой базы данных ожидает получать только явные даты и время из вашего кода. Это предупреждение появляется, когда он получает неявную дату и время. Это указывает на то, что вы не завершили портирование своего кода для поддержки часовых поясов. Обратитесь к руководству по миграции для получения советов по этому процессу.

    Тем временем, для обратной совместимости, дата и время считаются в часовом поясе по умолчанию, что обычно и ожидается.

  3. now.date() – это вчера! (или завтра)

    Если вы всегда использовали неявные даты и время, вы, вероятно, считаете, что можете преобразовать дату и время в дату, вызвав метод date(). Вы также считаете, что date очень похож на datetime, за исключением того, что он менее точен.

    Ничего из этого неверно в среде с поддержкой часовых поясов:

    >>> import datetime
    >>> import pytz
    >>> paris_tz = pytz.timezone("Europe/Paris")
    >>> new_york_tz = pytz.timezone("America/New_York")
    >>> paris = paris_tz.localize(datetime.datetime(2012, 3, 3, 1, 30))
    # This is the correct way to convert between time zones with pytz.
    >>> new_york = new_york_tz.normalize(paris.astimezone(new_york_tz))
    >>> paris == new_york, paris.date() == new_york.date()
    (True, False)
    >>> paris - new_york, paris.date() - new_york.date()
    (datetime.timedelta(0), datetime.timedelta(1))
    >>> paris
    datetime.datetime(2012, 3, 3, 1, 30, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
    >>> new_york
    datetime.datetime(2012, 3, 2, 19, 30, tzinfo=<DstTzInfo 'America/New_York' EST-1 day, 19:00:00 STD>)
    

    Как показывает этот пример, у одной и той же даты и времени разная дата в зависимости от часового пояса, в котором она представлена. Но реальная проблема более фундаментальна.

    Дата и время представляет собой точку во времени. Она абсолютна: она не зависит ни от чего. Напротив, дата – это календарное понятие. Это период времени, границы которого зависят от часового пояса, в котором рассматривается дата. Как вы можете видеть, эти два понятия фундаментально различаются, и преобразование даты и времени в дату – это не детерминированная операция.

    Что это означает на практике?

    В целом, следует избегать преобразования datetime в date. Например, вы можете использовать фильтр шаблонов date для отображения только части даты даты и времени. Этот фильтр преобразует дату и время в текущий часовой пояс перед форматированием, гарантируя, что результаты отображаются правильно.

    Если вам действительно нужно выполнить преобразование самостоятельно, вы должны убедиться, что дата и время сначала преобразуются в соответствующий часовой пояс. Обычно это будет текущий часовой пояс:

    >>> from django.utils import timezone
    >>> timezone.activate(pytz.timezone("Asia/Singapore"))
    # For this example, we just set the time zone to Singapore, but here's how
    # you would obtain the current time zone in the general case.
    >>> current_tz = timezone.get_current_timezone()
    # Again, this is the correct way to convert between time zones with pytz.
    >>> local = current_tz.normalize(paris.astimezone(current_tz))
    >>> local
    datetime.datetime(2012, 3, 3, 8, 30, tzinfo=<DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>)
    >>> local.date()
    datetime.date(2012, 3, 3)
    
  4. У меня ошибка “Are time zone definitions for your database and pytz installed?” pytz установлен, значит, проблема в базе данных?

    Если вы используете MySQL, см. раздел Определения часовых поясов в заметках по MySQL для получения инструкций по загрузке определений часовых поясов.

Использование

  1. У меня есть строка "2012-02-21 10:28:45" и я знаю, что она в часовом поясе "Europe/Helsinki" . Как преобразовать её в явную дату и время?

    Для этого как раз и предназначен pytz.

    >>> from django.utils.dateparse import parse_datetime
    >>> naive = parse_datetime("2012-02-21 10:28:45")
    >>> import pytz
    >>> pytz.timezone("Europe/Helsinki").localize(naive, is_dst=None)
    datetime.datetime(2012, 2, 21, 10, 28, 45, tzinfo=<DstTzInfo 'Europe/Helsinki' EET+2:00:00 STD>)
    

    Обратите внимание, что localize – это расширение pytz для API tzinfo. Также вам может потребоваться перехватить pytz.InvalidTimeError. В документации pytz содержатся дополнительные примеры. Вы должны их изучить перед попыткой манипулировать явными датами и временем.

  2. Как получить местное время в текущем часовом поясе?

    Ну, первый вопрос – а нужно ли вам это?

    Вы должны использовать местное время только при взаимодействии с людьми, и слой шаблонов предоставляет фильтры и теги для преобразования дат и времени в часовой пояс по вашему выбору.

    Кроме того, Python умеет сравнивать явные даты и время, учитывая смещения UTC при необходимости. Гораздо проще (и, возможно, быстрее) написать весь код модели и представления в UTC. Таким образом, в большинстве случаев даты и время в UTC, возвращаемые функцией django.utils.timezone.now(), будут достаточны.

    Однако, для полноты картины, если вам действительно нужно местное время в текущем часовом поясе, вот как его получить:

    >>> from django.utils import timezone
    >>> timezone.localtime(timezone.now())
    datetime.datetime(2012, 3, 3, 20, 10, 53, 873365, tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
    

    В этом примере pytz установлен, и текущий часовой пояс – "Europe/Paris".

  3. Как увидеть все доступные часовые пояса?

    pytz предоставляет помощники, включая список текущих часовых поясов и список всех доступных часовых поясов – некоторые из которых представляют только исторический интерес.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/1.9/topics/i18n/timezones/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API