269 votes

Convertir une date python en époque avec strftime

J'ai un temps en UTC à partir duquel je veux le nombre de secondes depuis l'époque.

J'utilise strftime pour le convertir en nombre de secondes. Prenons l'exemple du 1er avril 2012.

>>>datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

Le 1er avril 2012, l'UTC de l'époque est 1333238400 mais l'exemple ci-dessus renvoie 1333234800, ce qui est différent d'une heure.

Il semble donc que strftime prenne en compte l'heure de mon système et applique un décalage de fuseau horaire quelque part. Je pensais que datetime était purement naïf ?

Comment puis-je contourner ce problème ? Si possible, éviter d'importer d'autres bibliothèques, sauf si elles sont standard. (J'ai des soucis de portabilité).

0 votes

15 votes

Suis-je le seul à remarquer que vous utilisez des littéraux octaux dans les chiffres ?

513voto

jleahy Points 3678

Si vous voulez convertir une date python en secondes depuis l'époque, vous pouvez le faire explicitement :

>>> (datetime.datetime(2012,04,01,0,0) - datetime.datetime(1970,1,1)).total_seconds()
1333238400.0

En Python 3.3+, vous pouvez utiliser timestamp() à la place :

>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0

Pourquoi vous ne devez pas utiliser datetime.strftime('%s')

Python ne supporte pas réellement %s comme argument de strftime (si vous vérifiez à l'adresse http://docs.python.org/library/datetime.html#strftime-and-strptime-behavior il n'est pas dans la liste), la seule raison pour laquelle cela fonctionne est que Python transmet l'information à strftime de votre système, qui utilise votre fuseau horaire local.

>>> datetime.datetime(2012,04,01,0,0).strftime('%s')
'1333234800'

13 votes

Je suis devenu fou en essayant de comprendre pourquoi je vois souvent strftime("%s"), alors que ce n'est pas dans la documentation. Merci pour tout cela !

62 votes

N'utilisez pas .strftime("%s") il n'est pas supporté, il n'est pas portable, il peut silencieusement produire un résultat erroné pour un objet datetime conscient, il échoue si l'entrée est en UTC (comme dans la question) mais que le fuseau horaire local n'est pas UTC.

0 votes

Pourquoi échoue-t-il dans ce cas ? J'avais des problèmes similaires avec mktime.

109voto

BorrajaX Points 2576

J'ai eu de sérieux problèmes avec les fuseaux horaires et autres. La façon dont Python gère tout cela est assez déroutante (pour moi). Les choses semblent fonctionner correctement en utilisant le module calendrier (voir les liens suivants 1 , 2 , 3 et 4 ).

>>> import datetime
>>> import calendar
>>> aprilFirst=datetime.datetime(2012, 04, 01, 0, 0)
>>> calendar.timegm(aprilFirst.timetuple())
1333238400

7 votes

+1 parce que c'est la seule réponse qui fonctionne pour l'entrée de la question.

0 votes

Est-ce que c'est portable ?

0 votes

Il devrait l'être, oui.

37voto

srossross Points 408
import time
from datetime import datetime
now = datetime.now()

time.mktime(now.timetuple())

1 votes

C'est une façon incorrecte d'écrire time.time() ( mktime() peut échouer pendant les transitions DST alors que time.time() continue de fonctionner). Et il ne répond à la question que si le fuseau horaire local est UTC (l'entrée de la question est en UTC). Même si l'entrée représente une heure locale, alors mktime() peut également échouer pour les dates passées/futures s'il n'utilise pas la base de données tz et si le fuseau horaire local peut avoir des décalages utc différents au fil des ans, par exemple, Europe/Moscou en 2010-2015 -- utiliser l'heure UTC (comme dans la question) ou des objets datetime tenant compte du fuseau horaire à la place.

0 votes

Voici plus de problèmes avec la conversion d'une heure locale (telle que retournée par .now() ) à l'horodatage de l'époque (retourné par mktime() ) . Si vous l'avez lu, vous comprenez pourquoi l'entrée UTC (utilisée dans la question) est (beaucoup) plus préférable qu'un objet datetime naïf représentant l'heure locale.

16voto

Charles Plager Points 103
import time
from datetime import datetime
now = datetime.now()

# same as above except keeps microseconds
time.mktime(now.timetuple()) + now.microsecond * 1e-6

(Désolé, je n'ai pas pu commenter la réponse existante)

0 votes

C'est parce que time.mktime ne prend pas en compte la partie microseconde, n'est-ce pas ?

1 votes

Correct. La structure du tuple de temps (basée sur C strut) n'a pas d'espace pour les microsecondes, donc nous devons récupérer l'information de l'objet datetime et l'ajouter à la fin.

7voto

Marc Maxmeister Points 1789

Si vous avez juste besoin d'un timestamp en temps unix /epoch, cette seule ligne fonctionne :

created_timestamp = int((datetime.datetime.now() - datetime.datetime(1970,1,1)).total_seconds())
>>> created_timestamp
1522942073L

et ne dépend que de datetime fonctionne en python2 et python3

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X