Метка времени Unix для datetime в django с часовым поясом

у меня есть календарь javascript, который отправляет мне unixtimestamp. Я в Сингапуре. Я хочу, чтобы эта метка времени была интерпретирована как сингапурская метка времени, а затем преобразована в utc для сравнения с БД.

Я не могу, для жизни себя, выяснить, как сказать Джанго, что эта отметка времени из текущего часового пояса, Сингапур.

когда я делаю оператор печати метки времени, он добавляет 8 часов к времени (что означает, что django думает, что я вводил время в utc и локализует его в Сингапурском контексте)

среди многих других вещей, я старалась: start=datetime.datetime.fromtimestamp(int(start_date)).replace(tzinfo=get_current_timezone())

start_date - 1325376000 (что переводится как 2012-01-01 00:00:00)

однако, когда я печатаю вывод этого, я получаю 2012-01-01 08:00:00+06:55. Я даже не знаю, откуда приходит +06:55, когда Сингапур +08:00. Я заблудилась.

спасибо помощь.

settings.py:

TIME_ZONE = 'Asia/Singapore'

USE_TZ = True

3 ответов


предполагая, что у вас есть pytz установлено:

from datetime import datetime
import pytz
local_tz = pytz.timezone("Asia/Singapore") 
utc_dt = datetime.utcfromtimestamp(timestamp).replace(tzinfo=pytz.utc)
local_dt = local_tz.normalize(utc_dt.astimezone(local_tz))

например:

>>> from datetime import datetime
>>> import pytz
>>> local_tz = pytz.timezone("Asia/Singapore")
>>> utc_dt = datetime.utcfromtimestamp(1325376000).replace(tzinfo=pytz.utc)
>>> utc_dt
datetime.datetime(2012, 1, 1, 0, 0, tzinfo=<UTC>)
>>> local_dt = local_tz.normalize(utc_dt.astimezone(local_tz))
>>> local_dt
datetime.datetime(2012, 1, 1, 8, 0, tzinfo=<DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>)
>>> local_dt.replace(tzinfo=None)
datetime.datetime(2012, 1, 1, 8, 0)

передайте объект pytz tzinfo в fromtimestamp() способ:

#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz

tz = pytz.timezone("Asia/Singapore")
print(datetime.fromtimestamp(1325376000, tz))
# -> 2012-01-01 08:00:00+08:00

Примечание: объект результата-часовой пояс: вы можете сравнить его с другими объектами datetime, т. е. вам не нужно конвертировать его в UTC для сравнения-вы можете использовать его как есть.

я даже не знаю, откуда +06:55 приходит, когда Сингапур +08: 00.

видишь +06:55 из-за поврежденных .replace() звонок. get_current_timezone() возвращает pytz.timezone("Asia/Singapore") который имеет переменную смещение utc (оно может иметь другое смещение utc в разные даты). Когда вы звоните .replace() используется некоторый случайный (зависит от реализации) объект tzinfo. Проблема в том, что .replace() метод не позволяет pytz.timezone("Asia/Singapore") чтобы выбрать правильный tzinfo для даты ввода.

>>> list(tz._tzinfos.values())
[<DstTzInfo 'Asia/Singapore' MALT+7:00:00 STD>,
 <DstTzInfo 'Asia/Singapore' MALT+7:20:00 STD>,
 <DstTzInfo 'Asia/Singapore' JST+9:00:00 STD>,
 <DstTzInfo 'Asia/Singapore' SMT+6:55:00 STD>,
 <DstTzInfo 'Asia/Singapore' SGT+7:30:00 STD>,
 <DstTzInfo 'Asia/Singapore' MALT+7:30:00 STD>,
 <DstTzInfo 'Asia/Singapore' MALST+7:20:00 DST>,
 <DstTzInfo 'Asia/Singapore' LMT+6:55:00 STD>,
 <DstTzInfo 'Asia/Singapore' SGT+8:00:00 STD>]

то есть, оба +06:55 и +0800 действительны (в разные даты) для Сингапура. Вот почему вы должны использовать .replace() только с часовыми поясами, которые имеют постоянное смещение utc, такое как сам часовой пояс utc ( смещение равно нулю, всегда на любую дату).

fromtimestamp(,tz) вызовы метода tz.fromutc() внутри, что позволяет tz чтобы выбрать правильное смещение для заданного времени utc.


все методы выше valide, но не "django like". Вот простой пример того, как программист django сделал бы это:

from datetime import datetime

from django.utils.timezone import make_aware


# valid timestamp
value = 1531489250 
# you can pass the following obj to a DateTimeField, when your settings.USE_TZ == True
datetime_obj_with_tz = make_aware(datetime.fromtimestamp(value))

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