web-dev-qa-db-fra.com

Convertir un unixtime en un objet datetime et inversement (paire de fonctions de conversion temporelle inverses)

J'essaie d'écrire une paire de fonctions, dt et ut, qui convertissent dans les deux sens entre le temps Unix normal (secondes depuis le 1970-01-01 00:00:00 UTC) et un Python datetime.

Si dt et ut étaient des inverses appropriés, alors ce code imprimerait deux fois le même horodatage:

import time, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.fromtimestamp(u)
def ut(d): return time.mktime(d.timetuple())

u = 1004260000
print u, "-->", ut(dt(u))

Hélas, le deuxième horodatage est inférieur de 3 600 secondes (une heure) au premier. Je pense que cela ne se produit que pour des heures très particulières, peut-être pendant cette heure où l'heure d'été passe. Mais existe-t-il un moyen d'écrire dt et ut pour qu'ils soient de véritables inverses l'un de l'autre?

Question connexe: Rendre les inverses parfaits de matplotlib date2num et num2date

26
dreeves

Vous avez raison de dire que ce comportement est lié à l'heure d'été. Le moyen le plus simple d'éviter cela est de vous assurer que vous utilisez un fuseau horaire sans l'heure d'été, UTC est le plus logique ici.

datetime.datetime.utcfromtimestamp() et calendar.timegm() traitent les temps UTC et sont des inverses exacts.

import calendar, datetime

# Convert a unix time u to a datetime object d, and vice versa
def dt(u): return datetime.datetime.utcfromtimestamp(u)
def ut(d): return calendar.timegm(d.timetuple())

Voici un peu d'explication pourquoi datetime.datetime.fromtimestamp() a un problème avec l'heure d'été, à partir des documents:

Renvoie la date et l'heure locales correspondant à l'horodatage POSIX, telles que celles renvoyées par time.time(). Si l’argument facultatif tz est Aucun ou non spécifié, l’horodatage est converti en date et heure locales de la plate-forme et l’objet datetime retourné est naïf.

La partie importante ici est que vous obtenez un objet datetime.datetime Naïf, ce qui signifie qu'il n'y a aucune information de fuseau horaire (ou d'heure d'été) en tant que partie de l'objet. Cela signifie que plusieurs horodatages distincts peuvent mapper vers le même objet datetime.datetime Lorsque vous utilisez fromtimestamp(), s'il vous arrive de choisir des heures qui tombent pendant la restauration de l'heure d'été:

>>> datetime.datetime.fromtimestamp(1004260000) 
datetime.datetime(2001, 10, 28, 1, 6, 40)
>>> datetime.datetime.fromtimestamp(1004256400)
datetime.datetime(2001, 10, 28, 1, 6, 40)
39
Andrew Clark