Convertissez datetime en timestamp Unix et convertissez-le en python

j'ai dt = datetime(2013,9,1,11) , et je voudrais obtenir un horodatage Unix de cet objet datetime.

Quand je fais dt - datetime(1970,1,1)).total_seconds() j'ai eu le timestamp 1378033200 .

lors de sa conversion en utilisant datetime.fromtimestamp j'ai eu datetime.datetime(2013, 9, 1, 6, 0) .

L'heure ne correspond pas. Qu'ai-je manqué?

131
demandé sur Kun 2013-11-06 04:19:14

9 réponses

ce que vous avez manqué ici, ce sont des fuseaux horaires.

probablement vous avez cinq heures de congé UTC, donc 2013-09-01T11:00:00 local et 2013-09-01T06:00:00Z sont la même heure.

vous devez lire le haut des datetime docs, qui expliquent sur les fuseaux horaires et les objets" naïfs "et" conscients".

si votre DateTime naïve originale était UTC, la façon de le récupérer est d'utiliser utcfromtimestamp au lieu de fromtimestamp .

d'un autre côté, si votre datetime originale naïve était locale, vous n'auriez pas dû lui enlever une estampille de temps UTC; utilisez datetime.fromtimestamp(0) à la place.

ou, si vous aviez un objet aware datetime, vous devez soit utiliser une époque locale (aware) des deux côtés, soit convertir explicitement en UTC et à partir de UTC.

Si vous avez ou pouvez mettre à niveau, Python 3.3 ou ultérieure, vous pouvez éviter tous ces problèmes en utilisant simplement la méthode timestamp au lieu d'essayer de comprendre comment le faire vous-même. Et même si vous ne le faites pas, vous pourriez vouloir considérer en empruntant son code source .

(et si vous pouvez attendre Python 3.4, il semble que PEP 341 est susceptible de le faire dans la version finale, ce qui signifie que tout ce dont J. F. Sebastian et moi parlions dans les commentaires devrait être faisable avec juste le stdlib, et fonctionne de la même manière sur Unix et Windows.)

74
répondu abarnert 2013-11-22 19:23:28

solution

import time
import datetime
d = datetime.date(2015,1,5)

unixtime = time.mktime(d.timetuple())
100
répondu DmitrySemenov 2015-01-13 03:21:47

plutôt que cette expression pour créer une estampille temporelle POSIX de dt ,

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

utilisez ceci:

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

j'obtiens la bonne réponse dans votre exemple en utilisant la deuxième méthode.

EDIT: Certains de suivi... Après quelques commentaires (Voir ci-dessous), j'étais curieux du manque de support ou de documentation pour %s dans strftime . Voici ce que j'ai trouvé:

dans le source Python pour datetime et time , la chaîne STRFTIME_FORMAT_CODES nous dit:

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

donc maintenant si nous man strftime (sur les systèmes BSD tels que Mac OS X), vous trouverez un soutien pour %s :

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

de toute façon, c'est pourquoi %s fonctionne sur les systèmes qu'il fait. Mais il y a de meilleures solutions au problème de L'OP (qui prennent en compte les fuseaux horaires). Voir la réponse acceptée de @abarnert ici.

46
répondu Darren Stone 2015-01-14 06:31:09

si vous voulez convertir un python datetime en secondes depuis l'époque, vous devez le faire explicitement:

>>> 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

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

>>> import datetime
>>> datetime.datetime(2012,4,1,0,0).timestamp()
1333234800.0
27
répondu Francisco Tomé Costa 2018-04-09 14:18:06

si votre objet datetime représente L'heure UTC, n'utilisez pas l'heure.mktime, car il suppose que le tuple est dans votre fuseau horaire local. Au lieu de cela, utiliser le calendrier.timegm:

>>> import datetime, calendar
>>> d = datetime.datetime(1970, 1, 1, 0, 1, 0)
>>> calendar.timegm(d.timetuple())
60
3
répondu Matt Kramer 2017-11-28 07:10:50

Eh bien, lors de la conversion en timestamp unix, python suppose fondamentalement UTC, mais tout en convertissant en arrière, il vous donnera une date convertie à votre fuseau horaire local.

voir cette question / réponse; Obtenir le fuseau horaire utilisé par datetime.datetime.fromtimestamp ()

2
répondu Ronald Portier 2017-05-23 12:34:45

Vous avez raté le fuseau horaire info (déjà répondu, de l'accord)

arrow le paquet permet d'éviter cette torture avec des datetimes; il est déjà écrit, testé, pypi-publié, cross-python (2.6 - 3.XXème.)

Tout ce que vous devez: pip install arrow (ou ajouter des dépendances)

Solution pour votre cas

dt = datetime(2013,9,1,11)
arrow.get(dt).timestamp
# >>> 1378033200

bc = arrow.get(1378033200).datetime
print(bc)
# >>> datetime.datetime(2013, 9, 1, 11, 0, tzinfo=tzutc())
print(bc.isoformat())
# >>> '2013-09-01T11:00:00+00:00'
2
répondu maxkoryukov 2017-09-01 13:02:35
def dt2ts(dt):
    import calendar
    import time
    from dateutil import tz

    if dt.tzinfo is None:
        return int(time.mktime(dt.timetuple()))
    utc_dt = dt.astimezone(tz.tzutc()).timetuple()
    return calendar.timegm(utc_dt)

si vous voulez UTC timestamp: time.mktime juste pour local dt .Utiliser calendar.timegm est sûr mais dt doit la zone utc donc changer la zone en utc

1
répondu wyx 2017-11-29 04:00:44

pour travailler avec des fuseaux horaires UTC:

time_stamp = calendar.timegm(dt.timetuple())

datetime.utcfromtimestamp(time_stamp)
0
répondu Dede 2018-09-25 16:51:07