datetime.datetime.utcnow()
Чому для цього datetime
немає жодної інформації про часовий пояс, враховуючи, що це явно UTC datetime
?
Я би сподівався, що це буде містити tzinfo
.
datetime.datetime.utcnow()
Чому для цього datetime
немає жодної інформації про часовий пояс, враховуючи, що це явно UTC datetime
?
Я би сподівався, що це буде містити tzinfo
.
Відповіді:
Це означає, що це наївний часовий пояс, тому з ним не можна користуватися datetime.astimezone
Ви можете надати йому такий часовий пояс
import pytz # 3rd party: $ pip install pytz
u = datetime.utcnow()
u = u.replace(tzinfo=pytz.utc) #NOTE: it works only with a fixed utc offset
тепер ви можете змінити часові пояси
print(u.astimezone(pytz.timezone("America/New_York")))
Щоб отримати поточний час у заданому часовому поясі, ви можете передати tzinfo datetime.now()
безпосередньо:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
print(datetime.now(pytz.timezone("America/New_York")))
Він працює для будь-якого часового поясу, включаючи ті, що спостерігають літній час (DST), тобто працює для часових поясів, які можуть мати різний зміщення ультразвукового режиму в різний час (нефіксований зміщення потужності). Не використовуйте tz.localize(datetime.now())
- це може вийти з ладу під час переходу на кінець DST, коли місцевий час неоднозначний.
astimezone
. Таким чином, у datetime не тільки немає власних часових поясів, але єдина широкодоступна реалізація tzinfo не відповідає передбачуваному стандарту.
u=datetime.now(pytz.utc)
tz.localize(datetime.now())
; використовувати datetime.now(tz)
замість цього.
Зауважте, що для Python 3.2 далі datetime
модуль містить datetime.timezone
. Документація для datetime.utcnow()
:
Відомий поточний час UTC можна отримати зателефонувавши .
datetime.now
(
timezone.utc
)
Отже, ви можете зробити:
>>> import datetime
>>> datetime.datetime.now(datetime.timezone.utc)
datetime.datetime(2014, 7, 10, 2, 43, 55, 230107, tzinfo=datetime.timezone.utc)
datetime.now(timezone.utc)
або datetime.utcnow(timezone.utc)
?
datetime.utcnow()
не бере аргументів. Так і мало бути datetime.now(timezone.utc)
.
datetime.now()
поверне машинний час, але datetime.utcnow()
поверне фактичний час UTC.
datetime.utcnow()
не встановлено, tzinfo
щоб вказати, що це UTC. Але datetime.now(datetime.timezone.utc)
повертає час UTC з tzinfo
встановленим.
tz
об'єкт у теперішній конструктор, він поверне час цього часового поясу? Гаразд! Дякуємо, що вказали.
Стандартні бібліотеки Python не включають жодних класів tzinfo (але див. Pep 431 ). Я можу лише здогадуватися про причини. Особисто я думаю, що було помилкою не включати клас tzinfo для UTC, тому що це досить суперечливо, щоб мати стандартну реалізацію.
Редагувати: Хоча в бібліотеці немає жодної реалізації, в tzinfo
документації є приклад, наведений як приклад .
from datetime import timedelta, tzinfo
ZERO = timedelta(0)
# A UTC class.
class UTC(tzinfo):
"""UTC"""
def utcoffset(self, dt):
return ZERO
def tzname(self, dt):
return "UTC"
def dst(self, dt):
return ZERO
utc = UTC()
Щоб використовувати його, щоб отримати поточний час як усвідомлений об'єкт дати:
from datetime import datetime
now = datetime.now(utc)
Є datetime.timezone.utc
в Python 3.2+:
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
datetime
створених об'єктами utcnow()
) ...
timezone.utc
нарешті додано до Python 3.2. Для зворотної сумісності utcnow()
все одно повертає часовий об'єкт без часового поясу, але ви можете отримати те, що хочете, зателефонувавши now(timezone.utc)
.
struct
модуль здійснював би автоматичні перетворення з Unicode в bytestring, і остаточне рішення полягало в порушенні сумісності з більш ранніми версіями Python 3, щоб запобігти тому, щоб неправильне рішення не рухалося вперед.
tzinfo
документація Python включає в себе приклади коду для його реалізації, але вони не включають цю функціональність у саму дату! docs.python.org/2/library/datetime.html#datetime.tzinfo.fromutc
pytz
це чудовий ресурс. На той момент, коли я відредагував свою відповідь, щоб ввести приклад коду, хтось ще запропонував це, і я не хотів красти їхній грім.
pytz
Модуль є одним з варіантів, і є інший python-dateutil
, який , хоча і є також пакет третій партії, вже можуть бути доступні в залежності від інших залежностей і операційної системи.
Я просто хотів включити цю методику для довідки - якщо ви вже встановили python-dateutil
для інших цілей, ви можете використовувати її tzinfo
замість дублюванняpytz
import datetime
import dateutil.tz
# Get the UTC time with datetime.now:
utcdt = datetime.datetime.now(dateutil.tz.tzutc())
# Get the UTC time with datetime.utcnow:
utcdt = datetime.datetime.utcnow()
utcdt = utcdt.replace(tzinfo=dateutil.tz.tzutc())
# For fun- get the local time
localdt = datetime.datetime.now(dateutil.tz.tzlocal())
Я схильний погоджуватися, що дзвінки utcnow
повинні включати інформацію про часовий пояс UTC. Я підозрюю, що це не включено, оскільки в натільній бібліотеці дат за замовчуванням існують наївні дати для перехресної сумісності.
utcdt = datetime.datetime.utcfromtimestamp(1234567890).replace(dateutil.tz.tzutc())
datetime.now(pytz_tz)
цього завжди працює; datetime.now(dateutil.tz.tzlocal())
може вийти з ладу під час переходу DST . PEP 495 - Розбіжність у часі з місцевим часом може покращити dateutil
ситуацію в майбутньому.
utc_dt = datetime.fromtimestamp(1234567890, dateutil.tz.tzutc())
(зауважте: dateutil
з нефіксованим зміщенням utc (наприклад dateutil.tz.tzlocal()
), можливо, тут не вдасться , замість цього використовуйте рішення на pytz
основі базування ).
dateutil
для dateutil.parser
, мені сподобалося це рішення краще. Це було так просто , як: utcCurrentTime = datetime.datetime.now(tz=dateutil.tz.tzutc())
. Віола !!
Жульєн Даньджу написав хорошу статтю, в якій пояснив, чому ніколи не слід мати справу з часовими поясами . Уривок:
Дійсно, API datetime Python завжди повертає невідомі об’єкти datetime, що дуже прикро. Дійсно, як тільки ви отримуєте один з цього об’єкта, немає ніякого способу дізнатися, що таке часовий пояс, тому ці об’єкти самі по собі є досить «марними».
На жаль, навіть якщо ви можете використовувати utcnow()
, ви все одно не побачите інформацію про часовий пояс, як ви виявили.
Рекомендації:
Завжди використовуйте обізнані
datetime
об'єкти, тобто з інформацією про часовий пояс. Це гарантує можливість їх безпосереднього порівняння (свідомі та необізнаніdatetime
об’єкти не порівнянні) та поверне їх правильно користувачам. Використовуйте пітс, щоб мати об'єкти часового поясу.Використовуйте ISO 8601 як формат введення та виведення рядка. Використовувати
datetime.datetime.isoformat()
для повернення часових позначок у вигляді рядка, відформатованого за допомогою цього формату, який включає інформацію про часовий пояс.Якщо вам потрібно проаналізувати рядки, що містять часові позначки у форматі ISO 8601, ви можете розраховувати на те
iso8601
, що повертає часові позначки з правильною інформацією про часовий пояс. Це робить часові позначки безпосередньо порівнянними.
Щоб додати timezone
інформацію в Python 3.2+
import datetime
>>> d = datetime.datetime.now(tz=datetime.timezone.utc)
>>> print(d.tzinfo)
'UTC+00:00'
AttributeError: 'module' object has no attribute 'timezone'
Python 2.7.13 (за замовчуванням, 19 січня 2017, 14:48:08)
from datetime import datetime
from dateutil.relativedelta import relativedelta
d = datetime.now()
date = datetime.isoformat(d).split('.')[0]
d_month = datetime.today() + relativedelta(months=1)
next_month = datetime.isoformat(d_month).split('.')[0]
Дати UTC не потребують інформації про часовий пояс, оскільки вони є UTC, що за визначенням означає, що вони не мають зміщення.
pytz.utc
). Зауважте, що велика різниця між значенням, зсув якого від UTC невідомий, і значенням, де воно, як відомо, дорівнює 0. Останнє - те, що utcnow()
має повернутись, IMO. Це вписується в "Усвідомлений об'єкт використовується для відображення конкретного моменту часу, який не піддається інтерпретації" відповідно до документації.