J'ai dt = datetime(2013,9,1,11)
, et j'aimerais obtenir un horodatage Unix de cet objet datetime.
Quand je le fais, (dt - datetime(1970,1,1)).total_seconds()
je reçois l'horodatage 1378033200
.
Lors de la reconversion en utilisant datetime.fromtimestamp
j'ai obtenu datetime.datetime(2013, 9, 1, 6, 0)
.
L'heure ne correspond pas. Qu'est-ce que j'ai manqué ici?
timestamp
méthode au lieu d'essayer de le faire vous-même. D'une part, cela évite complètement la possibilité de soustraire les temps naïfs de différents fuseaux horaires.dt
vient-il? Est-ce une heure locale ou une heure UTC?Réponses:
Ce que vous avez manqué ici, ce sont les fuseaux horaires.
Vous avez probablement 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 de la
datetime
documentation, qui explique les fuseaux horaires et les objets «naïfs» et «conscients».Si votre datetime naïf d'origine était UTC, le moyen de le récupérer est d'utiliser à la
utcfromtimestamp
place defromtimestamp
.D'un autre côté, si votre datetime naïve d'origine était locale, vous n'auriez pas dû en soustraire un horodatage UTC en premier lieu; utiliser à la
datetime.fromtimestamp(0)
place.Ou, si vous aviez un objet datetime conscient, vous devez soit utiliser une époque locale (consciente) des deux côtés, soit convertir explicitement vers et depuis UTC.
Si vous avez ou pouvez mettre à niveau vers Python 3.3 ou version ultérieure, vous pouvez éviter tous ces problèmes en utilisant simplement la
timestamp
méthode au lieu d'essayer de comprendre comment le faire vous-même. Et même si vous ne le faites pas, vous pouvez envisager d' emprunter son code source .(Et si vous pouvez attendre Python 3.4, il semble que PEP 341 est susceptible de faire partie de la version finale, ce qui signifie que tout ce dont JF Sebastian et moi parlions dans les commentaires devrait être faisable avec juste la bibliothèque stdlib, et fonctionnant de la même manière sous Unix et Windows.)
la source
dt
est dans le fuseau horaire local, alors la formule de la question est incorrectedatetime.fromtimestamp(0)
(époque dans le fuseau horaire actuel) doit être utilisée à la place dedatetime(1970, 1,1)
(époque unix en UTC).fromtimestamp(0)
peut échouer si le système ne stocke pas les informations de fuseau horaire historique, par exemple sous Windows.pytz
pourrait être utilisé dans ce cas.pytz
n'aide pas à moins que vous ne sachiez déjà dans quel fuseau horaire vous vous trouvez; Pour ce faire par programme, vous avez besoin d'une bibliothèque différente qui obtient le fuseau horaire Windows actuel et le convertit enpytz
fuseau horaire et / ou le recherche par nom.tzlocal
module qui fonctionne également sous Windows. Voici comment vous pouvez convertir l'heure UTC en heure locale .la solution est
la source
d
s'agit d'un objet date / date / heure naïf qui représente l'heure locale (il peut échouer pour des heures ambiguës ou pour des dates passées / futures si le système d'exploitation ne fournit pas d'historique tz db (le décalage UTC peut avoir été différent dans le passé dans le fuseau horaire)). Plus d'options .Si vous souhaitez convertir une date / heure python en secondes depuis l'époque, vous devez le faire explicitement:
Dans Python 3.3+, vous pouvez utiliser à la
timestamp()
place:la source
%s
, car il sera localisé sur l'horloge du système sur lequel vous vous trouvez actuellement. Vous ne devriez jamais l'utiliser que.timestamp()
pour obtenir l'heure Epoch / UNIX correcte.%s
ne fonctionne pas sur les systèmes Windows (ValueError: Invalid format string
)8
ou9
Plutôt que cette expression pour créer un horodatage POSIX
dt
,Utilisez ceci:
J'obtiens la bonne réponse dans votre exemple en utilisant la deuxième méthode.
EDIT: Quelques suivis ... Après quelques commentaires (voir ci-dessous), j'étais curieux de savoir le manque de support ou de documentation pour
%s
instrftime
. Voici ce que j'ai trouvé:Dans la source Python pour
datetime
ettime
, la chaîneSTRFTIME_FORMAT_CODES
nous dit:Alors maintenant, si nous
man strftime
(sur les systèmes BSD tels que Mac OS X), vous trouverez un support pour%s
:Quoi qu'il en soit, c'est pourquoi il
%s
fonctionne sur les systèmes qu'il utilise. Mais il existe de meilleures solutions au problème d'OP (qui prennent en compte les fuseaux horaires). Voir la réponse acceptée de @ abarnert ici.la source
strftime("%s")
dans la documentation, je viens de confirmer que cela fonctionne sur Mac et Linux. Merci.time.strftime()
et ladatetime.strftime
documentation déléguent à lastrftime(3)
fonction de plates-formes pour les directives non prises en charge.%s
peut échouer même sous Mac OS X, par exemple, datetime.strftime ('% s') doit respecter tzinfo .%s
car vous n'utiliserez que l'heure système localisée du système sur lequel vous êtes. Vous souhaitez utiliser.timestamp()
si vous essayez d'obtenir le véritable horodatage UNIX.Pour travailler avec les fuseaux horaires UTC:
la source
Vous avez manqué les informations sur le fuseau horaire (déjà répondu, accepté)
arrow
package permet d'éviter cette torture avec les datetimes; Il est déjà écrit, testé, publié pypi, cross-python (2.6 - 3.xx).Tout ce dont vous avez besoin:
pip install arrow
(ou ajouter aux dépendances)Solution pour votre cas
la source
Si votre objet datetime représente l'heure UTC, n'utilisez pas time.mktime, car il suppose que le tuple est dans votre fuseau horaire local. Au lieu de cela, utilisez calendar.timegm:
la source
Eh bien, lors de la conversion en horodatage UNIX, python suppose fondamentalement UTC, mais lors de la conversion, il vous donnera une date convertie dans votre fuseau horaire local.
Voir cette question / réponse; Récupère le fuseau horaire utilisé par datetime.datetime.fromtimestamp ()
la source
Si vous voulez un horodatage UTC:
time.mktime
juste pour le dt local .Usecalendar.timegm
est sûr mais dt doit la zone utc alors changez la zone en utc. Si dt en UTC, utilisez simplementcalendar.timegm
.la source
la source
Cette classe couvrira vos besoins, vous pouvez passer la variable dans ConvertUnixToDatetime et appeler la fonction sur laquelle vous voulez qu'elle opère.
la source