Python: как получить значение datetime.сегодня() это "часовой пояс в курсе"?
Я пытаюсь вычесть одно значение даты из значения datetime.today() чтобы вычислить, как давно было-то. Но он жалуется:
TypeError: can't subtract offset-naive and offset-aware datetimes
значение datetime.today() Не кажется, что "часовой пояс знает", в то время как мое другое значение даты. Как я могу получить значение datetime.today() что часовой пояс в курсе? Прямо сейчас он дает мне время по местному времени, которое бывает PST, т. е. UTC-8hrs. В худшем случае, есть ли способ вручную ввести значение часового пояса в
14 ответов:
в стандартной библиотеке нет кросс-платформенного способа создания осведомленных часовых поясов без создания собственного класса часовых поясов.
на Windows, есть
win32timezone.utcnow(), но это часть pywin32. Я бы скорее предложил использовать pytz библиотека, который имеет постоянно обновляемую базу самых часовых поясов.работа с локальными часовыми поясами может быть очень сложной (см. ссылки "дальнейшее чтение" ниже), поэтому вы можете использовать UTC во всем своем приложении, специально для арифметических операций, таких как вычисление разницы между двумя временными точками.
вы можете получить текущую дату/время вот так:
import pytz from datetime import datetime datetime.utcnow().replace(tzinfo=pytz.utc)ум, что
datetime.today()иdatetime.now()вернуть местные время, а не время UTC, поэтому применение.replace(tzinfo=pytz.utc)им было бы не правильно.еще один хороший способ сделать это:
datetime.now(pytz.utc), который немного короче и делает то же самое.
дальнейшее чтение / просмотр зачем предпочитаю UTC во многих случаях:
- pytz documentation
- Что Каждый Разработчик Должен Знать О Времени – советы по разработке для многих реальных случаев использования
- проблема со временем и часовыми поясами-Computerphile – забавное, открывающее глаза объяснение о сложности работы с часовыми поясами (видео)
получить текущее время, в определенном часовом поясе:
import datetime import pytz my_date = datetime.datetime.now(pytz.timezone('US/Pacific'))
в Python 3 стандартная библиотека делает это намного проще:
>>> import datetime >>> datetime.datetime.now(datetime.timezone.utc) datetime.datetime(2016, 8, 26, 14, 34, 34, 74823, tzinfo=datetime.timezone.utc)Если вам нужно решение, которое использует только стандартную библиотеку и работает как в Python 2, так и в Python 3, см. ответ Дж. Ф. Себастьяна.
вот решение stdlib, которое работает как на Python 2, так и на 3:
from datetime import datetime now = datetime.now(utc) # timezone-aware datetime.utcnow() today = datetime(now.year, now.month, now.day, tzinfo=utc) # midnightздесь
today- это знают экземпляр класса datetime, представляющий начало суток (полночь) по Гринвичу иutcявляется объектом tzinfo (пример из документации):from datetime import tzinfo, timedelta ZERO = timedelta(0) class UTC(tzinfo): def utcoffset(self, dt): return ZERO def tzname(self, dt): return "UTC" def dst(self, dt): return ZERO utc = UTC()обзоры: сравнение производительности несколько способов получить полночь (начало дня) для данного времени UTC.
Примечание: это более сложно, чтобы полуночный на часовом поясе с нефиксированное смещение относительно UTC.
другой метод построения объекта datetime с учетом часового пояса, представляющего текущее время:
import datetime import pytz pytz.utc.localize( datetime.datetime.utcnow() )
Если вы используете Django, вы можете установить даты, не связанные с TZ (только utc).
комментарий следующая строка settings.py:
USE_TZ = True
вот один из способов создать его с помощью stdlib:
import time from datetime import datetime FORMAT='%Y-%m-%dT%H:%M:%S%z' date=datetime.strptime(time.strftime(FORMAT, time.localtime()),FORMAT)дата будет хранить локальную дату и смещение от UTC, а не дата в часовом поясе UTC, поэтому вы можете использовать это решение, если вам нужно определить в каком часовом поясе генерируется дата. В этом примере и в моем местном часовом поясе:
date datetime.datetime(2017, 8, 1, 12, 15, 44, tzinfo=datetime.timezone(datetime.timedelta(0, 7200))) date.tzname() 'UTC+02:00'ключ добавить
%zдиректива для формата представления, чтобы указать смещение UTC сгенерированного структура времени. С другими форматами представления можно ознакомиться в модуле datetime docsЕсли вам нужна дата в часовом поясе UTC, вы можете заменить времени.местное время() С времени.gmtime()
date=datetime.strptime(time.strftime(FORMAT, time.gmtime()),FORMAT) date datetime.datetime(2017, 8, 1, 10, 23, 51, tzinfo=datetime.timezone.utc) date.tzname() 'UTC'Edit
это работает только на python3. Директива z недоступна на python 2 _strptime.py код
почему не использовать dateutil, как описано здесь: http://joelinoff.com/blog/?p=802
from dateutil.tz import tzlocal # Get the current date/time with the timezone. now = datetime.datetime.now(tzlocal())
получение даты с учетом часового пояса в
utcчасовой пояс достаточно для вычитания даты, чтобы работать.но если вы хотите дату с учетом часового пояса в вашем текущем часовом поясе,
tzlocalпуть:from tzlocal import get_localzone # pip install tzlocal from datetime import datetime datetime.now(get_localzone())PS
dateutilимеет аналогичную функцию (dateutil.tz.tzlocal). Но несмотря на совместное использование имени у него есть совершенно другая база кода, которая как отметить по J. F. Себастьян может дать неправильные результаты.
вы можете создать локальную
timezoneС помощьюdatetimeпутем разбора вывода atime.strftimeвызова, который использует%zдиректива (введена в Python 3.3), Как показано jcazor. Вы можете использоватьtimezoneчтобы создать awaredatetimeэкземпляр с одной строкой:import time from datetime import datetime aware_local_now = datetime.now( tz=datetime.strptime(time.strftime("%z", time.localtime()), "%z").tzinfo) print(aware_local_now) 2018-03-01 13:41:26.753644-08:00
использовать часовой пояс как показано ниже для часового пояса известно время даты, по умолчанию UTC:
from django.utils import timezone today = timezone.now()
Если вы получаете текущее время и дату в python,то импортируйте дату и время, пакет pytz в python после того, как вы получите текущую дату и время, например..
from datetime import datetime import pytz import time str(datetime.strftime(datetime.now(pytz.utc),"%Y-%m-%d %H:%M:%S%t"))
еще одна альтернатива, на мой взгляд, лучше, использует
Pendulumвместоpytz. Рассмотрим следующий простой код:>>> import pendulum >>> dt = pendulum.now().to_iso8601_string() >>> print (dt) 2018-03-27T13:59:49+03:00 >>>чтобы установить маятник и посмотреть их документацию, перейдите здесь. Он имеет тонны вариантов (например, простой ISO8601, RFC3339 и многие другие поддержка формата), более высокую производительность и, как правило, дают более простой код.
Comments