Konvertovať dátum na časovú značku Unixu a konvertovať ju späť v jazyku python

Mám dt = datetime(2013,9,1,11) a chcel by som získať unixovú časovú pečiatku tohto objektu datetime.

Keď urobím (dt - datetime(1970,1,1)).total_seconds(), dostanem časovú pečiatku 1378033200.

Pri spätnom prevode pomocou datetime.fromtimestamp som dostal datetime.datetime(2013, 9, 1, 6, 0).

Hodina sa nezhoduje. Čo som tu prehliadol?

Riešenie

Čo ste tu vynechali, sú časové pásma.

Pravdepodobne máte päť hodín mimo UTC, takže 2013-09-01T11:00:00 miestneho času a 2013-09-01T06:00:00Z je rovnaký čas.

Musíte si prečítať hornú časť dokumentácie datetime, ktorá vysvetľuje časové pásma a "naive" a "aware" objekty.

Ak bol váš pôvodný naive datetime UTC, spôsob, ako ho obnoviť, je použiť utcfromtimestamp namiesto fromtimestamp.

Na druhej strane, ak bol váš pôvodný naivný dátumový čas lokálny, nemali by ste od neho v prvom rade odčítať časovú značku UTC; namiesto toho použite datetime.fromtimestamp(0).

Alebo, ak ste mali uvedomelý objekt datetime, musíte buď použiť lokálnu (uvedomelú) epochu na oboch stranách, alebo explicitne konvertovať na a z UTC.

Ak máte Python 3.3 alebo novší, alebo naň môžete prejsť, môžete sa všetkým týmto problémom vyhnúť tak, že jednoducho použijete metódu timestamp namiesto toho, aby ste sa snažili zistiť, ako to urobiť sami. A aj keď nemáte, možno budete chcieť zvážiť požičanie si jeho zdrojového kódu.

(A ak si môžete počkať na Python 3.4, vyzerá to tak, že PEP 341 sa pravdepodobne dostane do finálnej verzie, čo znamená, že všetky veci, o ktorých sme s J. F. Sebastianom hovorili v komentároch, by mali byť realizovateľné len so stdlib a fungovať rovnako na Unixe aj Windows.)

Komentáre (9)

Namiesto tohto výrazu vytvorte časovú pečiatku POSIX z dt,

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

Použite toto:

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

Správnu odpoveď vo vašom príklade dostanem použitím druhej metódy.

EDIT: Niekoľko doplňujúcich informácií... Po niektorých pripomienkach (pozri nižšie) som sa zaujímal o nedostatočnú podporu alebo dokumentáciu pre %s v strftime. Tu je to, čo som našiel:

V Python source pre datetime a time nám reťazec STRFTIME_FORMAT_CODES hovorí:

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

Takže ak teraz man strftime (na systémoch BSD, ako je Mac OS X), nájdete podporu pre %s:

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

Každopádne, preto %s funguje na systémoch, na ktorých funguje. Existujú však lepšie riešenia problému OP'a (ktoré zohľadňujú časové pásma). Pozri @abarnert'a akceptovanú odpoveď tu.

Komentáre (9)

Pri konverzii DO unixovej časovej značky python v podstate predpokladá UTC, ale pri spätnej konverzii vám poskytne dátum prepočítaný na vaše miestne časové pásmo.

Pozri túto otázku/odpoveď; https://stackoverflow.com/questions/18812638/get-timezone-used-by-datetime-datetime-fromtimestamp

Komentáre (0)