Как получить изоформатную строку даты и времени, включающую часовой пояс по умолчанию? - PullRequest
48 голосов
/ 04 августа 2010

Мне нужно создать строку времени, которая соответствует ISO-формату yyyy-mm-ddThh:mm:ss.ssssss-ZO:NE. Методы класса now() и utcnow() почти делают то, что я хочу.

>>> import datetime
>>> #time adjusted for current timezone
>>> datetime.datetime.now().isoformat()
'2010-08-03T03:00:00.000000'
>>> #unadjusted UTC time
>>> datetime.datetime.utcnow().isoformat()
'2010-08-03T10:00:00.000000'
>>>
>>> #How can I do this?
>>> datetime.datetime.magic()
'2010-08-03T10:00:00.000000-07:00'

Ответы [ 5 ]

69 голосов
/ 27 января 2015

Чтобы получить текущее время в UTC в Python 3.2 +:

>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).isoformat()
'2015-01-27T05:57:31.399861+00:00'

Чтобы получить местное время в Python 3.3 +:

>>> from datetime import datetime, timezone
>>> datetime.now(timezone.utc).astimezone().isoformat()
'2015-01-27T06:59:17.125448+01:00'

Объяснение: datetime.now(timezone.utc) создает объект datetime с указанием часового пояса во времени UTC.astimezone() затем изменяет часовой пояс объекта datetime на часовой пояс системы, если он вызывается без аргументов.Объекты datetime с указанием часового пояса автоматически генерируют правильный формат ISO.

34 голосов
/ 04 августа 2010

Вы должны сделать так, чтобы ваш часовой пояс объектов даты-времени был осведомлен. из документов datetime :

Существует два вида объектов даты и времени: «наивный» и «осведомленный». Это различие относится к тому, имеет ли объект какое-либо представление о часовом поясе, переходе на летнее время или другой вид алгоритмической или политической корректировки времени. То, представляет ли наивный объект дата-время Всемирное координированное время (UTC), местное время или время в каком-либо другом часовом поясе, зависит только от программы, так же как от программы зависит, представляет ли конкретное число метры, мили или массу. Наивные объекты даты и времени легко понять и работать с ними за счет игнорирования некоторых аспектов реальности.

Если у вас есть осведомленный объект datetime, вы можете использовать isoformat () и получить нужный вам вывод.

Чтобы ваши объекты даты-времени были осведомлены, вам нужно подкласс tzinfo, как во втором примере здесь , или проще - использовать пакет, который сделает это за вас, например pytz или python-dateutil

Используя pytz, это будет выглядеть так:

import datetime, pytz
datetime.datetime.now(pytz.timezone('US/Central')).isoformat()

Вы также можете управлять форматом вывода, если вы используете strftime с директивой формата '% z' подобно

datetime.datetime.now(pytz.timezone('US/Central')).strftime('%Y-%m-%dT%H:%M:%S.%f%z')
17 голосов
/ 17 апреля 2015

С стрелка :

>>> import arrow
>>> arrow.now().isoformat()
'2015-04-17T06:36:49.463207-05:00'
>>> arrow.utcnow().isoformat()
'2015-04-17T11:37:17.042330+00:00'
3 голосов
/ 22 октября 2016

Вы можете сделать это в Python 2.7+ с помощью python-dateutil (который по умолчанию установлен на Mac):

>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> datetime.now(tzlocal()).isoformat()
'2016-10-22T12:45:45.353489-03:00'

Или вы, если хотите конвертировать из существующей хранимой строки:

>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from dateutil.parser import parse
>>> parse("2016-10-21T16:33:27.696173").replace(tzinfo=tzlocal()).isoformat()
'2016-10-21T16:33:27.696173-03:00' <-- Atlantic Daylight Time (ADT) 
>>> parse("2016-01-21T16:33:27.696173").replace(tzinfo=tzlocal()).isoformat()
'2016-01-21T16:33:27.696173-04:00' <-- Atlantic Standard Time (AST)
0 голосов
/ 04 августа 2010

Что-то вроде следующего примера.Обратите внимание, я нахожусь в Восточной Австралии (UTC + 10 часов в данный момент).

>>> import datetime
>>> dtnow = datetime.datetime.now();dtutcnow = datetime.datetime.utcnow()
>>> dtnow
datetime.datetime(2010, 8, 4, 9, 33, 9, 890000)
>>> dtutcnow
datetime.datetime(2010, 8, 3, 23, 33, 9, 890000)
>>> delta = dtnow - dtutcnow
>>> delta
datetime.timedelta(0, 36000)
>>> hh,mm = divmod((delta.days * 24*60*60 + delta.seconds + 30) // 60, 60)
>>> hh,mm
(10, 0)
>>> "%s%+02d:%02d" % (dtnow.isoformat(), hh, mm)
'2010-08-04T09:33:09.890000+10:00'
>>>
...