Я пытаюсь вычесть одно значение даты из значения, datetime.today()
чтобы вычислить, как давно что-то было. Но это жалуется
TypeError: can't subtract offset-naive and offset-aware datetimes
Значение datetime.today()
не похоже на «часовой пояс», в то время как мое другое значение даты. Как я могу получить значение datetime.today()
этого с учетом часового пояса?
Прямо сейчас, это дает мне время по местному времени, которое бывает PST, то есть UTC - 8 часов. В худшем случае, есть ли способ, которым я могу вручную ввести значение часового пояса в datetime
объект, возвращаемый datetime.today()
и установить его на UTC-8?
Конечно, идеальным решением было бы автоматическое определение часового пояса.
datetime.now().astimezone()
начиная с Python 3.6Ответы:
В стандартной библиотеке нет кроссплатформенного способа создания осведомленных часовых поясов без создания собственного класса часовых поясов.
В Windows есть
win32timezone.utcnow()
, но это часть pywin32. Я бы предпочел использовать библиотеку pytz , которая имеет постоянно обновляемую базу данных большинства часовых поясов.Работа с местными часовыми поясами может быть очень сложной (см. Ссылки «Дальнейшее чтение» ниже), поэтому вы, скорее всего, захотите использовать UTC во всем приложении, особенно для арифметических операций, таких как вычисление разницы между двумя временными точками.
Вы можете получить текущую дату / время следующим образом:
Помните об этом
datetime.today()
иdatetime.now()
верните местное время, а не время UTC, поэтому обращение.replace(tzinfo=pytz.utc)
к ним будет неправильным.Еще один хороший способ сделать это:
который немного короче и делает то же самое.
Дальнейшее чтение / просмотр, почему во многих случаях предпочитают UTC:
источник
datetime.now(pytz.utc)
вместоdatetime.utcnow().replace(tzinfo = pytz.utc)
?now(utc)
не возвращается сегодня (если в UTC нет полуночи), возвращает текущее время в UTC. Вы также.replace(hour=0, minute=0, ...)
должны получить начало дня (какdatetime.today()
)today()
возвращает текущее время, а не в полночь. Если есть случай использования, где требуется полночь, да, замена должна быть сделана соответственно. Поскольку первоначальный вопрос касался разницы между датой и временем, я не думаю, что требуется полночь.datetime.today()
это такcombine(date.today(), time())
.datetime
имеет оба.now()
и.today()
методы, которые (как вы правильно указали) возвращают (почти) одно и то же. Там нетdate.now()
метода.date
иdatetime
объекты не являются взаимозаменяемыми. Использование объекта datetime вместоdate
объекта может привести к незначительным ошибкам; Я не вижу причин дляdatetime.today()
существования, если это почти копияdatetime.now()
.timezone.now()
вместо,datetime.now()
так как он будет использовать UTC автоматически, еслиUSE_TZ = True
.timezone
находится по адресуdjango.utils.timezone
: документация: docs.djangoproject.com/en/1.11/topics/i18n/timezonesПолучить текущее время в определенном часовом поясе:
источник
datetime.datetime(2016, 11, 5, 9, 43, 45, tzinfo=pytz.timezone('US/Pacific'))
и посмотрите, ожидали ли вы этогоВ Python 3 стандартная библиотека значительно упрощает определение UTC в качестве часового пояса:
Если вам нужно решение, которое использует только стандартную библиотеку и работает как в Python 2, так и в Python 3, см. Ответ jfs .
Если вам нужен местный часовой пояс, а не UTC, см . Ответ Михая Капотэ
источник
Вот решение stdlib, которое работает на Python 2 и 3:
где
today
- осведомленный экземпляр datetime, представляющий начало дня (полночь) в UTC иutc
представляющий собой объект tzinfo ( пример из документации ):Связанный: сравнение производительности нескольких способов получить полночь (начало дня) для данного времени UTC . Примечание: сложнее получить полночь для часового пояса с нефиксированным смещением UTC .
источник
Другой метод для создания объекта datetime с информацией о часовом поясе, представляющего текущее время:
источник
pytz.utc
иpytz.UTC
оба определены (и являются одинаковыми)replace()
часовой пояс обычно склонен к ошибкам в большинстве других применений, в то времяlocalize()
как предпочтительный способ присвоения часового пояса наивным временным меткам является предпочтительным..localize()
метод терпит неудачу в течение неоднозначного локального времени (не входящий в UTC) Ответ @ philfreo, который использует,.now(pytz_timezone)
продолжает работать в таких случаях..now(pytz_timezone)
делает то же самое, что иlocalize(utcnow)
- сначала он генерирует текущее время в UTC, затем назначает ему часовой пояс: "<...> В этом случае результат эквивалентенtz.fromutc(datetime.utcnow().replace(tzinfo=tz))
". Оба ответа верны и работают всегда.pytz
через OLSON db должна знать, как преобразовать его в любой часовой пояс в мире. Осведомленность о любом другом наивном (не являющемся) часовом поясе времени затруднена из-за неоднозначности во время смены летнего времени. Это не проблема.localize
(кормить егоis_dst
значение, оно будет работать на любую дату). Это неотъемлемая проблема практики летнего времени.Однострочник, использующий только стандартную библиотеку, работает, начиная с Python 3.3. Вы можете получить
datetime
объект, осведомленный о местном часовом поясе, используяastimezone
(как предложено johnchen902 )источник
datetime.now()
можно вызывать без каких-либо аргументов и возвращать правильный локальный результат (datetime
предполагается, что наивные s находятся в местном часовом поясе).Если вы используете Django , вы можете установить даты, не поддерживающие tz (только UTC ).
Прокомментируйте следующую строку в settings.py:
источник
pytz - это библиотека Python, которая позволяет выполнять точные и кроссплатформенные вычисления часовых поясов с использованием Python 2.3 или выше.
С помощью stdlib это невозможно.
Смотрите аналогичный вопрос на SO .
источник
Вот один из способов его создания с помощью stdlib:
date будет хранить локальную дату и смещение от UTC , а не дату в часовом поясе UTC, поэтому вы можете использовать это решение, если вам необходимо определить, в каком часовом поясе сгенерирована дата . В этом примере и в моем местном часовом поясе:
Ключ добавляет
%z
директиву в представление FORMAT, чтобы указать смещение UTC сгенерированной временной структуры. С другими форматами представления можно ознакомиться в документации модуля datetime.Если вам нужна дата в часовом поясе UTC, вы можете заменить time.localtime () на time.gmtime ()
редактировать
Это работает только на python3 . Директива z недоступна в коде Python 2 _strptime.py
источник
Используйте dateutil, как описано в Python datetime.datetime.now (), который учитывает часовой пояс :
источник
tzlocal()
функция по-прежнему является одним из самых простых решений, и ее обязательно стоит упомянуть здесь.Получение даты с
utc
учетом часового пояса в часовом поясе достаточно для вычитания даты для работы.Но если вам нужна дата с
tzlocal
учетом часового пояса в вашем текущем часовом поясе, можно пойти по следующему пути:PS
dateutil
имеет аналогичную функцию (dateutil.tz.tzlocal
). Но, несмотря на то, что он разделяет название, у него совершенно другая кодовая база, которая, как отметил Дж.Ф. Себастьян, может давать неверные результаты.источник
Вот решение с использованием читаемого часового пояса, которое работает с today ():
Вы можете перечислить все часовые пояса следующим образом:
источник
Специально для часовых поясов без UTC:
Единственный часовой пояс, который имеет свой собственный метод, это
timezone.utc
, но вы можете пометить часовой пояс с любым смещением UTC, если вам нужно, используяtimedelta
&timezone
, и принудительно используя его.replace
.Использование
timezone(timedelta(hours=n))
в качестве часового пояса настоящей серебряной пули здесь, и у нее есть много других полезных приложений.источник
Если вы получите текущее время и дату в python, то импортируйте дату и время, пакет pytz в python после того, как вы получите текущую дату и время, например, как ..
источник
Другая альтернатива, на мой взгляд, лучшая, использует
Pendulum
вместоpytz
. Рассмотрим следующий простой код:Чтобы установить Pendulum и посмотреть их документацию, перейдите сюда . У него множество опций (например, простая поддержка ISO8601, RFC3339 и многих других форматов), лучшая производительность и, как правило, более простой код.
источник
Используйте часовой пояс, как показано ниже, для времени с учетом часового пояса. По умолчанию используется UTC:
источник
Тайлер из 'howchoo' сделал действительно замечательную статью, которая помогла мне лучше понять объекты Datetime, ссылка ниже
Работа с Datetime
по сути, я просто добавил следующее в конец обоих моих объектов datetime
Пример:
источник
попробуйте pnp_datetime , все время, которое использовалось и было возвращено, относится к часовому поясу и не вызовет каких-либо смещенных наивных и смещенных проблем.
источник
Следует подчеркнуть, что начиная с Python 3.6 вам нужен только стандартный lib, чтобы получить объект datetime с информацией о часовом поясе, представляющий местное время (настройку вашей ОС). Использование astimezone ()
(см. комментарий @ johnchen902).
источник