Управление настройками часовых поясов для каждого объекта в Django

У меня есть приложение Django, в котором пользователь может создать Activity, а затем для Activity создайте несколько записей журнала. Действие имеет созданное время и время, а запись в журнале также имеет созданное время и дату.

Действие должно быть создано с часовым поясом создающего пользователя в момент его создания. В частности, данный пользователь может иметь две операции в отдельных часовых поясах; настройка часового пояса не для каждого пользователя, а для активности. Я могу получить текущее смещение пользователя из UTC в JavaScript в браузере (и я рад этому полагаться).

Я не знаю, как сохранить эти времена в базе данных, а затем правильно отобразить их при рендеринге?

У меня включен USE_TZ. Здесь, в Великобритании, все работает: при создании Activity я сохраняю созданное datetime как django.utils.timezone.now() , и я сохраняю текущее смещение пользователя (из JavaScript) как timezoneHoursOffset в активность. Затем, когда я показываю записи Activity и ее записи на странице, я обертываю это в {% timezone) Etc/GMT + (timezoneHoursOffset) "%} ... {% endtimezone%} .

Однако этот подход не работает, если сервер не находится в Великобритании. Время сохраняется в базе данных в формате UTC (я проверил это, проверив в самой базе данных, не используя ORM), это время затем «изменяется» ORM на восемь часов после UTC (поскольку часовой пояс сервера UTC-8) (и это дает правильное время!), А затем тег {% timezone%} вычитает еще один восемь часов с момента времени, что означает, что отображаемое время за восемь часов до того, что должно быть.

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

1
nl ja de

2 ответы

Ref ответ , часовой пояс «Etc/GMT» имеют свои знак обратный. Например, я нахожусь в +0800, он должен быть 'Etc/GMT-8' вместо 'Etc/GMT + 8' (и я подозреваю, что ваш UTC -8 действительно должен быть "Etc/GMT + 8" ):

>>> from django.template import Template, Context
>>> from django.utils.timezone import now
>>> print(Template("""{% load tz %}
localtime: {{ t }}
Etc/GMT-8: {{ t|timezone:"Etc/GMT-8" }}
Etc/GMT+8: {{ t|timezone:"Etc/GMT+8" }}
""").render(Context({'t':now()})))

localtime: Jan. 29, 2013, 11:48 p.m.
Etc/GMT-8: Jan. 29, 2013, 11:48 p.m.
Etc/GMT+8: Jan. 29, 2013, 7:48 a.m.

Таким образом, вы должны отменить свой timezoneHoursOffset ...

Для хранения БД в соответствии с doc , лучше хранить данные в UTC.

Кроме того, вы должны убедиться, что ваш JavaScript генерирует правильное смещение часа из-за DST. Если вы можете, лучше сохранить имя часового пояса и использовать его соответствующим образом.

1
добавлено
гений. Это именно то, что я делал неправильно. Спасибо.
добавлено автор sil, источник
from datetime import datetime
from dateutil import zoneinfo

from_zone = zoneinfo.gettz('UTC')
to_zone = zoneinfo.gettz('UK/UK') 

utc = created # your datetime object from the db

# Tell the datetime object that it's in UTC time zone since 
# datetime objects are 'naive' by default
utc = utc.replace(tzinfo=from_zone)

# Convert time zone
eastern_time = utc.aztimezone(to_zone)
1
добавлено
Тогда вы должны создать для этого настройки. Позвольте пользователю сохранить свой часовой пояс. Вы можете использовать приведенный выше код в режиме экономии времени. Я также сделал это, я разрешаю пользователю выбирать самостоятельно.
добавлено автор catherine, источник
Я обновляю свой ответ, я не знаю, если это действительно помогает вам.
добавлено автор catherine, источник
Это установит часовой пояс для всего сеанса. Если я показываю более одного действия на странице, тогда у них могут быть разные часовые пояса, поэтому они должны отображаться по-разному.
добавлено автор sil, источник
Ах, именно то, чего я избегаю, - это иметь часовые пояса для каждого пользователя; они относятся к активности. Данный пользователь может иметь две операции в разных часовых поясах; не существует одного часового пояса, который применяется ко всем действиям пользователя.
добавлено автор sil, источник
Django
Django
1 931 участник(ов)

Полезная информация и правила: https://github.com/django-ru/faq Вакансии и резюме: @django_jobs Пофлудить идём сюда: @django_flood Статистика чата: combot.org/chat/-1001063854692

django_jobs
django_jobs
916 участник(ов)

Поиск и предложения работы (Django) Правила: https://t.me/django_jobs/4 Вакансии с тегом #job улетают в канал @django_jobs_board Вопросы к @amureki Основной чат @pydjango

Django
Django
733 участник(ов)

Веб-фреймворк для перфекционистов с дедлайнами. Наша группа на vk: https://vk.com/django_framework В Discord: https://discord.me/django_framework по всем вопросам @MechanisM

django flood
django flood
71 участник(ов)

Флудилка джангистов Пока без правил