Python: как получить значение datetime.сегодня() это "часовой пояс в курсе"?



Я пытаюсь вычесть одно значение даты из значения datetime.today() чтобы вычислить, как давно было-то. Но он жалуется:



TypeError: can't subtract offset-naive and offset-aware datetimes


значение datetime.today() Не кажется, что "часовой пояс знает", в то время как мое другое значение даты. Как я могу получить значение datetime.today() что часовой пояс в курсе? Прямо сейчас он дает мне время по местному времени, которое бывает PST, т. е. UTC-8hrs. В худшем случае, есть ли способ вручную ввести значение часового пояса в

734   14  

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 во многих случаях:

получить текущее время, в определенном часовом поясе:

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

pytz это библиотека Python, которая позволяет выполнять точные и кросс-платформенные вычисления часового пояса с использованием Python 2.3 или выше.

с помощью stdlib это невозможно.

посмотреть похожие на вопрос так.

вот один из способов создать его с помощью 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 путем разбора вывода a 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 после того, как вы получите текущую дату и время, например..

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

    Ничего не найдено.