У меня есть timestamptz
поле с информацией о часовом поясе в PostgreSQL. Когда я извлекаю данные из таблицы, я хочу вычесть время прямо сейчас, чтобы узнать его возраст.
Проблема, с которой я столкнулся, заключается в том, что оба datetime.datetime.now()
и, datetime.datetime.utcnow()
похоже, возвращают временные метки, не зная метки времени, в результате чего я получаю эту ошибку:
TypeError: can't subtract offset-naive and offset-aware datetimes
Есть ли способ избежать этого (желательно без использования стороннего модуля).
РЕДАКТИРОВАТЬ: Спасибо за предложения, однако попытка отрегулировать часовой пояс, кажется, дает мне ошибки ... так что я просто собираюсь использовать временные метки, не зависящие от часового пояса в PG, и всегда вставлять, используя
NOW() AT TIME ZONE 'UTC'
Таким образом, все мои временные метки по умолчанию установлены в формате UTC (хотя это более раздражает).
datetime.timezone.utc
илиpytz.utc
. Например,1970-01-01 00:00:00
неоднозначна , и вы должны добавить часовой пояс на неоднозначность:1970-01-01 00:00:00 UTC
. Вы видите, вы должны добавить новую информацию; временная метка сама по себе неоднозначна.utcnow
не следует возвращать наивный объект или метку времени без часового пояса. Из документов: «Осведомленный объект используется для представления определенного момента времени, который не открыт для интерпретации». Любое время в UTC соответствует этому критерию по определению.Правильным решением является добавление информации о часовом поясе, например, чтобы получить текущее время как осведомленный объект datetime в Python 3:
В более старых версиях Python вы можете определить
utc
объект tzinfo самостоятельно (пример из документа datetime):затем:
источник
Я знаю, что некоторые люди используют Django специально как интерфейс для абстрагирования этого типа взаимодействия с базой данных. Django предоставляет утилиты, которые можно использовать для этого:
Вам необходимо настроить базовую инфраструктуру настроек Django, даже если вы просто используете интерфейс этого типа (в настройках вы должны включить,
USE_TZ=True
чтобы узнать дату и время).Само по себе это, вероятно, далеко не достаточно, чтобы мотивировать вас использовать Django в качестве интерфейса, но есть много других преимуществ. С другой стороны, если вы споткнулись здесь, потому что искали приложение Django (как я), то, возможно, это поможет ...
источник
USE_TZ=True
, чтобы узнать дату и время здесь.+ timedelta(hours=5, minutes=30)
для ISTЭто очень простое и понятное решение.
Две строки кода
Вывод: вы должны управлять переменными даты и времени с одинаковой информацией времени
источник
diff = datetime.now(timezone.utc) - your_timezone_aware_variable
работает (и(a - b)
формула выше, это объяснение, почему(a - b)
может работать, даже еслиa.tzinfo
нетb.tzinfo
).Модуль psycopg2 имеет свои собственные определения часовых поясов, поэтому я написал свою обертку вокруг utcnow:
и просто использовать
pg_utcnow
всякий раз, когда вам нужно текущее время для сравнения с PostgreSQLtimestamptz
источник
Я тоже столкнулся с той же проблемой. Тогда я нашел решение после долгих поисков.
Проблема заключалась в том, что когда мы получаем объект datetime из модели или формы, он учитывает смещение, а если мы получаем время по системе, он смещается наивно .
Поэтому я получил текущее время с помощью timezone.now () и импортировал часовой пояс из django.utils import timezone и поместил USE_TZ = True в файл настроек вашего проекта.
источник
Я придумал очень простое решение:
Он работает как с данными о часовом поясе, так и с указанием даты и времени. И никакие дополнительные библиотеки или обходные пути базы данных не требуются.
источник
Я нашел,
timezone.make_aware(datetime.datetime.now())
что полезно в Django (я на 1.9.1). К сожалению, вы не можете просто сделатьdatetime
объект осведомленным о смещении, тогдаtimetz()
это. Вы должны сделатьdatetime
и сравнить на основе этого.источник
Есть ли какая-то неотложная причина, почему вы не можете обработать вычисление возраста в самом PostgreSQL? Что-то вроде
источник
Я знаю, что это старо, но просто подумал, что добавлю свое решение на тот случай, если кто-то посчитает его полезным.
Я хотел сравнить местное наивное время-дату с осведомленным временем-датой с сервера времени. Я в основном создал новый наивный объект datetime, используя осведомленный объект datetime. Это что-то вроде хака и выглядит не очень красиво, но выполняет свою работу.
... здесь приходит выдумка ...
источник
utc_to_local()
из моего ответа возвращается местное время как осведомленный объект datetime (это код Python 3.3+)delta = response.tx_time - time.time()
.