Конвертиране на дата и час в Unix времеви отпечатък и превръщането му обратно в python

Имам dt = datetime(2013,9,1,11) , и бих искал да получа dt = datetime(2013,9,1,11) на Unix на този обект datetime.

Когато правя dt - datetime(1970,1,1)).total_seconds() , имам времеви клейма от 1378033200 .

Когато конвертирате обратно, използвайки datetime.fromtimestamp получих datetime.datetime(2013, 9, 1, 6, 0) .

Часът не съвпада. Какво пропуснах тук?

136
06 нояб. попита Кун 06 ноември. 2013-11-06 03:19 '13 в 3:19 2013-11-06 03:19
@ 9 отговора

Това, което сте пропуснали тук, са часовите зони.

Предполага се, че имате 5 часа от UTC, така че 2013-09-01T11: 00: 00 local и 2013-09-01T06: 00: 00Z е същото време.

Трябва да прочетете най-горната част на документите, които разказват за часовите зони и "наивните" и "осведомени" обекти.

Ако началният ви наивен datetime беше UTC, начинът да го възстановите е да използвате utcfromtimestamp вместо от fromtimestamp .

От друга страна, ако първоначалният ви наивен datetime е локален, не трябва да изваждате от него времевия отпечатък на UTC; вместо това използвайте datetime.fromtimestamp(0) .

Или, ако разполагате с обоснован обект на datetime, трябва или да използвате локална (осъзната) ера от двете страни, или да я конвертирате изрично към и от UTC.

Ако имате или можете да надстроите до Python 3.3 или по-нова версия, можете да избегнете всички тези проблеми, като просто използвате метода timestamp , вместо да се опитвате да разберете как да го направите сами. И дори да не го направите, можете да помислите за заемане на изходния код .

(И ако можете да изчакате Python 3.4, изглежда, че PEP 341 най-вероятно ще бъде включен във финалната версия, което означава всички неща на JF Sebastian и казах, че в коментарите това трябва да се прави само с stdlib и да работят същото като на Unix и Windows.)

78
06 нояб. отговорът е даден на 06 ноември. 2013-11-06 03:27 '13 в 3:27 2013-11-06 03:27

решението

border=0
 import time import datetime d = datetime.date(2015,1,5) unixtime = time.mktime(d.timetuple()) 
105
13 янв. Отговор, даден от Дмитрий Семенов 13 януари 2015-01-13 06:21 '15 в 6:21 2015-01-13 06:21

Вместо това, изразът за създаване на POSIX времеви отпечатък от dt ,

 (dt - datetime(1970,1,1)).total_seconds() 

Използвайте това:

 int(dt.strftime("%s")) 

Получавам правилния отговор във вашия пример, използвайки втория метод.

EDIT: някои последващи действия ... След някои коментари (виж по-долу) бях любопитен за липсата на поддръжка или документация за %s в strftime . Ето какво намерих:

В източника на Python за datetime и time низа STRFTIME_FORMAT_CODES ни казва:

 "Other codes may be available on your platform. See documentation for the C library strftime function." 

Така че, ако сме man strftime (в BSD системи като Mac OS X), ще намерите подкрепа за %s :

 "%s is replaced by the number of seconds since the Epoch, UTC (see mktime(3))." 

Във всеки случай защо %s работи върху системите, които прави. Но има по-ефективни решения на проблема с ОП (което взема предвид часовите зони). Вижте приетия отговор @abarnert тук.

47
06 нояб. отговорът е даден от Дарън Стоун 06 ноември. 2013-11-06 03:32 '13 в 3:32 2013-11-06 03:32

Ако искате да конвертирате датата и времето на Python до секунди от началото на ерата, трябва да го направите изрично:

 >>> import datetime >>> datetime.datetime(2012,04,01,0,0).strftime('%s') '1333234800' >>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds() 1333238400.0 

В Python 3. 3+ можете вместо това да използвате timestamp() :

 >>> import datetime >>> datetime.datetime(2012,4,1,0,0).timestamp() 1333234800.0 
33
23 янв. Отговор, даден от Франсиско Томе Коста на 23 януари 2017-01-23 20:03 '17 в 20:03 2017-01-23 20:03

Ако вашият обект datetime представлява UTC време, не използвайте time.mktime, тъй като приема, че tuple е във вашата местна часова зона. Вместо това използвайте calendar.timegm:

 >>> import datetime, calendar >>> d = datetime.datetime(1970, 1, 1, 0, 1, 0) >>> calendar.timegm(d.timetuple()) 60 
3
28 нояб. Отговорът е даден от Мат Крамер на 28 ноември. 2017-11-28 09:39 '17 в 9:39 2017-11-28 09:39

Е, когато конвертирате timestamp в unix, python основно приема UTC, но когато го конвертирате обратно, ще ви даде датата, преобразувана в часовата зона.

Вижте този въпрос / отговор; Вземете часовата зона, използвана от datetime.datetime.fromtimestamp ()

2
06 нояб. отговор, даден от Роналд Портиер Ноември 06 2013-11-06 03:33 '13 в 3:33 2013-11-06 03:33

За да работите с часовите зони на UTC:

 time_stamp = calendar.timegm(dt.timetuple()) datetime.utcfromtimestamp(time_stamp) 
2
25 сент. отговор, даден Dede 25 септември. 2018-09-25 19:51 '18 в 19:51 ч. 2018-09-25 19:51

Пропуснали сте информацията за часовата зона (вече сте отговорили, съгласни сте)

arrow пакет избягва това изтезание с datetime; Вече е написано, тествано, публикувано от pypi, cross-python (2.6 - 3.xx).

Всичко, от което се нуждаете е: pip install arrow (или добавете към зависимости)

Решение за вашия случай

2
01 сент. отговор, даден maxkoryukov 01 sep . 2017-09-01 16:02 '17 в 16:02 часа 2017-09-01 16:02
 def dt2ts(dt, utc=False): if utc: return calendar.timegm(dt.timetuple()) if dt.tzinfo is None: return int(time.mktime(dt.timetuple())) utc_dt = dt.astimezone(tz.tzutc()).timetuple() return calendar.timegm(utc_dt) 

Ако имате нужда от UTC timestamp: time.mktime само за локални dt. Използвайте calendar.timegm безопасно, но dt трябва да указва зоната utc, така че променете зоната на utc. Ако dt е в UTC, просто използвайте calendar.timegm .

1
29 нояб. отговорът е даден wyx 29 ноември 2017-11-29 07:00 '17 в 7:00 часа 2017-11-29 07:00

Други въпроси относно тагове или Ask a Question