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
- Что Каждый Разработчик Должен Знать О Времени – советы по разработке для многих реальных случаев использования
- проблема со временем и часовыми поясами-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 и utc
является объектом tzinfo (пример из docs):
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'
редактировать
это работает только на 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
). Но несмотря на совместное использование имени, он имеет совершенно другую кодовую базу, которая как отметить Дж. Ф. Себастьян может дать неверные результаты.
вы можете создать локальную timezone
С помощью datetime
парсинг вывода time.strftime
вызова, который использует %z
директива (введена в Python 3.3), Как показано jcazor. Вы можете использовать timezone
чтобы создать aware datetime
экземпляр с однострочным:
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 после того, как вы получите текущую дату и время, как as..
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 и многих других), лучшую производительность и, как правило, дает более простой код.