Як перетворити об’єкт time.struct_time в об’єкт datetime?


288

Як перетворити об’єкт Python time.struct_timeв datetime.datetimeоб’єкт?

У мене є бібліотека, яка забезпечує першу та другу бібліотеку, яка хоче другу.

Відповіді:


384

Використовуйте time.mktime (), щоб перетворити набір часу (у локальний час) у секунди з епохи, а потім використовуйте datetime.fromtimestamp (), щоб отримати об'єкт datetime.

from datetime import datetime
from time import mktime

dt = datetime.fromtimestamp(mktime(struct))

45
Зауважте, що це не вдається до 1900 року. Ви сучасні люди ніколи не пам’ятаєте про це обмеження!
mlissner

3
це втратить tm_isdstдані? Я думаю , що це так, в результаті чого DATETIME об'єкт залишається наївним до такої міри , щоб повернутися Noneна , .dst()навіть якщо struct.tm_isdstце 1.
n611x007

3
Зазвичай це спрацює. Однак він не вийде, якщо часовий проміжок перевищує значення, які приймає mktime, наприклад для значення (1970, 1, 1, 0, 0, 0, 0, 1, -1). Я зіткнувся з цим після розбору заголовка Date на HTTP-запиті, який повернув цей кортеж.
користувач3820547

3
@richvdh: C стандарт визначає, що mktime()слід tm_isdstвраховувати і Python time.mktime()викликає mktime()функцію C на CPython. mktime()може вибрати неправильний локальний час, коли він неоднозначний (наприклад, під час переходу після закінчення DST ("відпадання")), якщо struct.tm_isdstє -1або якщо mktime()на даній платформі ігнорується вхід tm_isdst . Крім того, якщо локальний часовий пояс мав різний зміщення ультразвукового сигналу в минулому, а C mktime()не використовує історичну базу даних tz, яка може забезпечити старі значення зміщення utc, то mktime()може також повернути неправильне (наприклад, за годину) значення.
jfs

1
@naxa: якщо mktime()не ігнорує tm_isdstдану платформу (це робиться на моїй), то fromtimestamp()однозначно втрачає інформацію: повернений наївний datetime об'єкт, що представляє місцевий час, може бути неоднозначним (часова мітка -> місцевий час детерміновано (якщо ми ігноруємо стрибкові секунди), але local time -> timestamp may be ambiguous e.g., during end-of-DST transition). Also, fromtimestamp () `може обрати неправильне зміщення утта, якщо воно не використовує історичну базу даних tz.
jfs

123

Подобається це:

>>> structTime = time.localtime()
>>> datetime.datetime(*structTime[:6])
datetime.datetime(2009, 11, 8, 20, 32, 35)

3
Не забувайте #import time, datetime
jhwist

7
@jhwist - деякі речі людям можна довіритись, щоб зрозуміти це самостійно :)
orip

14
@rodling the *і **синтаксис дозволяє розширити об'єкт типу listy або dicty, щоб розділити аргументи - це один з моїх улюблених фрагментів прекрасності Python. Дивіться docs.python.org/2/tutorial/… для отримання додаткової інформації
OrganicPanda

10
Просто пам’ятайте, що це дасть вам ValueError, якщо у Stru_time є проміжок секунди, наприклад:t=time.strptime("30 Jun 1997 22:59:60", "%d %b %Y %H:%M:%S"); datetime.datetime(*t[:6])
berdario

7
@berdario: повернути значення, сумісні з datetime: datetime(*t[:5]+(min(t[5], 59),))наприклад, прийняти "2015-06-30 16:59:60 PDT".
jfs

37

Це не пряма відповідь на ваше запитання (на яке вже досить відповіли). Однак, кілька разів перекусивши мене на фундаменті, я не можу наголосити на тому, щоб переконатись у тому, що надає ваш об'єкт time.struct_time, порівняно з тим, що можуть мати інші часові поля.

Якщо припустити, що у вас є як об'єкт time.struct_time, так і якийсь інший рядок дати / часу, порівняйте їх і будьте впевнені, що ви не втрачаєте дані і ненавмисно створюєте наївний об’єкт часу, коли ви можете зробити інакше.

Наприклад, відмінний модуль подачі даних поверне "опубліковане" поле і може повернути об'єкт time.struct_time у поле "опублікований_розбір":

time.struct_time(tm_year=2013, tm_mon=9, tm_mday=9, tm_hour=23, tm_min=57, tm_sec=42, tm_wday=0, tm_yday=252, tm_isdst=0)

Тепер зауважте, що ви насправді отримуєте з "опублікованим" полем.

Mon, 09 Sep 2013 19:57:42 -0400

За Stallman Борода «s! Інформація про часовий пояс!

У цьому випадку ледачий чоловік може захотіти використовувати відмінний модуль датування для збереження інформації про часовий пояс:

from dateutil import parser
dt = parser.parse(entry["published"])
print "published", entry["published"])
print "dt", dt
print "utcoffset", dt.utcoffset()
print "tzinfo", dt.tzinfo
print "dst", dt.dst()

що дає нам:

published Mon, 09 Sep 2013 19:57:42 -0400
dt 2013-09-09 19:57:42-04:00
utcoffset -1 day, 20:00:00
tzinfo tzoffset(None, -14400)
dst 0:00:00

Тоді можна було б використовувати об'єкт дати, що знає часовий пояс, щоб нормалізувати весь час на UTC або все, що, на вашу думку, є приголомшливим.


7
Всі *_parsedполя з feedparsed вже нормалізовані на UTC, як це можна перевірити в документації для аналізу дат, тому це зайве.
itorres

1
@itorres: Якщо я це розумію, ця відповідь стосується не нормалізації UTC, а збереження інформації часового поясу в datetimeоб'єкті, який втрачається при feedparserсинтаксичному синтаксичному аналізу строків.
davidag
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.