Получить локальный часовой пояс в джанго
У меня есть значение mysql DATETIME
, которое хранится в системном времени, UTC. Мне нужно преобразовать это в мой локальный часовой пояс в джанго. Вот что я сейчас имею:
# value in mysql
`timestamp`
2013-02-01 22:48:45
# settings.py
TIME_ZONE = 'America/Los_Angeles'
# views.py
last_updated = PathLastUpdated.objects.all()[0].timestamp
print last_updated
2013-02-01 22:48:45 <-- same as UTC
Как мне получить значение last_updated в моем локальном часовом поясе = "Америка/Лос-Анджелес"?
Ответы
Ответ 1
Документация Django для часовых поясов документирует все необходимые детали для преобразования объектов datetime
и времени в соответствующий часовой пояс для отображения.
Ваши данные хранятся в UTC, что хорошо. Когда вы получаете объект поля DateTime
из базы данных, он будет наивным объектом datetime.datetime
. т.е. дата/время без привязки часового пояса. Тогда вам решать сделать преобразование.
Пользователь вашего веб-приложения может находиться в разных часовых поясах, поэтому преобразование в соответствующий часовой пояс должно происходить для каждого запроса. Вот почему есть функция активации, чтобы установить текущий часовой пояс.
Если у вас установлен pytz, вы сможете сделать следующее:
from django.utils.timezone import activate
activate(settings.TIME_ZONE)
Все выходные данные поля даты в шаблонизаторе автоматически преобразуют наивные объекты даты и времени в правильный часовой пояс для отображения.
Если у вас есть только один наивный экземпляр datetime.datetime
, для которого вы хотите установить часовой пояс, просто используйте модуль pytz
напрямую. Хотя это не является нормальным для ваших представлений, так как рекомендуется преобразовывать часовой пояс только в точке представления.
from pytz import timezone
settings_time_zone = timezone(settings.TIME_ZONE)
last_updated = last_updated.astimezone(settings_time_zone)
Ответ 2
После многого плакала я могу показать правильную дату, когда моя страна сделает что-то вроде этого:
>>> from django.utils.timezone import get_current_timezone
>>> from front.models import Training
>>> tz = get_current_timezone()
>>> stored_date = Training.objects.first().start_date
datetime.datetime(2015, 4, 25, 17, 0, tzinfo=<UTC>)
>>> desired_date = stored_date + tz.utcoffset(stored_date)
datetime.datetime(2015, 4, 25, 14, 0, tzinfo=<UTC>)
Атрибут tzinfo
показывает utc, но дата и время отображаются правильно.
ОБНОВЛЕНИЕ 30/10/2015 (Django 1.8)
Сегодня я использую другой подход, более дружественный django
>>> from django.utils import timezone
>>> from trainings.models import Training
>>> value = Training.objects.first().date
>>> value
datetime.datetime(2015, 10, 23, 11, 32, 54, 633151, tzinfo=<UTC>)
>>> timezone.localtime(value)
datetime.datetime(2015, 10, 23, 9, 32, 54, 633151, tzinfo=<django.utils.timezone.LocalTimezone object at 0x7fa6129784a8>)
Ответ 3
localtime - это фильтр шаблонов, это может быть полезно.
https://github.com/django/django/blob/1.8.4/django/utils/timezone.py#L298
Пример кода:
from django.utils.timezone import localtime
desired_datetime = localtime(stored_datetime)
Ответ 4
Я создал простую промежуточную версию для обработки всего этого материала для вас:
https://github.com/Miserlou/django-easy-timezones
Просто установите его и следуйте инструкциям, и все готово!
-
Установите django-easy-timezones
pip install django-easy-timezones pytz pygeoip
-
Добавьте "easy-timezones" к настройкам INSTALLED_APPS следующим образом:
INSTALLED_APPS = (
...
'easy-timezones',
)
-
Добавьте EasyTimezoneMiddleware в MIDDLEWARE_CLASSES
MIDDLEWARE_CLASSES = (
...
'easy-timezones.middleware.EasyTimezoneMiddleware',
)
-
Добавьте в свой файл настроек путь к базе MaxMind GeoIP:
GEOIP_DATABASE = '/path/to/your/geoip/database/GeoIP.dat'
-
Включить локальное время в ваших шаблонах.
{% load tz %}
The UTC time is {{ object.date }}
{% localtime on %}
The local time is {{ object.date }}
{% endlocaltime %}
-
Тада!
Ответ 5
Я пришел к той же проблеме. В моих настройках я установил TIME_ZONE
, но время в MySql все еще указано в формате UTC.
# settings.py
TIME_ZONE = 'Asia/Shanghai'
Затем я обнаружил, что в settings.py для USE_TZ
установлено значение False
USE_TZ = False
Как отмечает @MagicLAMP, он работает только для сайта с одним часовым поясом, проверьте часовые пояса, является ли ваш сайт международным или происходит ли переход на летнее время при использовании вашего сайта.
Ответ 6
Я лично советовал бы использовать параметр TIME_ZONE
, отличный от UTC. Я помню, что у меня были проблемы с этим в прошлом, будь то база данных работала в другом часовом поясе (сохранение значений в другой часовой пояс), чем использовался бэкэнд Django. Это означало много хлопот, чтобы сравнивать времена, меняя их вперед и назад в зависимости от того, что вы делаете.
Хорошей практикой является, как правило, использование одного часового пояса в бэкэнде (см. UTC) и конвертирование времени в интерфейсе в часовой пояс пользователей, который вы обслуживаете.
Ответ 7
1: определить часовой пояс на ваш взгляд
from django.utils import timezone
variable = timezone.now()
2: тогда используйте это в своем шаблоне
{% load l10n %}
Teresina, {{variable |localize}}.
Ответ 8
Просто используйте
timezone.localtime(arg)
Ответ 9
Мне потребовалось некоторое время, чтобы найти это, но я так решил. Я думаю, пользовательский часовой пояс от IP-адреса, а затем сделать это в Django 2 и далее:
{% load tz %}
{% timezone "Europe/Paris" %}
Paris time: {{ object.date }}
{% endtimezone %}