Je traite des dates en Python et j'ai besoin de les convertir en timestamps UTC pour les utiliser en Javascript. dans Javascript. Le code suivant ne fonctionne pas :
>>> d = datetime.date(2011,01,01)
>>> datetime.datetime.utcfromtimestamp(time.mktime(d.timetuple()))
datetime.datetime(2010, 12, 31, 23, 0)
Convertir d'abord l'objet date en datetime n'aide pas non plus. J'ai essayé l'exemple de ce [lien][1], mais.. :
from pytz import utc, timezone
from datetime import datetime
from time import mktime
input_date = datetime(year=2011, month=1, day=15)
et maintenant soit :
mktime(utc.localize(input_date).utctimetuple())
ou
mktime(timezone('US/Eastern').localize(input_date).utctimetuple())
fonctionne.
Donc question générale : comment puis-je obtenir une date convertie en secondes depuis l'époque selon UTC ?
[1] : http://www.reddit.com/r/Python/comments/hkw9u/create_utc_timestamp_for_given_date
Si d = date(2011, 1, 1)
est en UTC :
>>> from datetime import datetime, date
>>> import calendar
>>> timestamp1 = calendar.timegm(d.timetuple())
>>> datetime.utcfromtimestamp(timestamp1)
datetime.datetime(2011, 1, 1, 0, 0)
Si d
est dans le fuseau horaire local :
>>> import time
>>> timestamp2 = time.mktime(d.timetuple()) # DO NOT USE IT WITH UTC DATE
>>> datetime.fromtimestamp(timestamp2)
datetime.datetime(2011, 1, 1, 0, 0)
timestamp1
et timestamp2
peuvent différer si minuit dans le fuseau horaire local n'est pas la même instance temporelle que minuit en UTC.
mktime()
peut renvoyer un résultat erroné si d
correspond à une heure locale ambiguë (par exemple, pendant la transition DST) ou si d
est une date passée (future) où le décalage utc aurait pu être différent et le C mktime()
n'a pas accès à la base de données tz sur la plate-forme donnée. Vous pourriez utiliser le module pytz
(par exemple, via tzlocal.get_localzone()
) pour avoir accès à la base de données tz sur toutes les plateformes. De plus, utcfromtimestamp()
peut échouer et mktime()
peut retourner un timestamp non-POSIX si le "right"
timezone est utilisé.
Pour convertir l'objet datetime.date
qui représente la date en UTC sans calendar.timegm()
:
DAY = 24*60*60 # POSIX day in seconds (exact value)
timestamp = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * DAY
timestamp = (utc_date - date(1970, 1, 1)).days * DAY
Pour convertir un objet datetime.datetime
(pas datetime.date
) qui représente déjà le temps en UTC en l'horodatage POSIX correspondant (un float
).
from datetime import timezone
timestamp = dt.replace(tzinfo=timezone.utc).timestamp()
Note : Il est nécessaire de fournir explicitement timezone.utc
sinon .timestamp()
suppose que votre objet datetime naïf est dans le fuseau horaire local.
Extrait de la documentation de datetime.utcfromtimestamp()
:
Il n'y a pas de méthode pour obtenir l'horodatage à partir d'une instance de datetime, mais l'horodatage POSIX correspondant à une instance de datetime dt peut être facilement calculé comme suit. Pour un dt naïf :
timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
Et pour un dt conscient :
timestamp = (dt - datetime(1970,1,1, tzinfo=timezone.utc)) / timedelta(seconds=1)
Lecture intéressante : Epoch time vs. time of day sur la différence entre Quelle heure est-il? et Combien de secondes se sont écoulées?.
Voir aussi : datetime needs an "epoch" ; method
Pour adapter le code ci-dessus à Python 2 :
timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
où timedelta.total_seconds()
équivaut à (td.microsecondes + (td.secondes + td.jours * 24 * 3600) * 10**6) / 10**6
calculée avec la division réelle activée.
from __future__ import division
from datetime import datetime, timedelta
def totimestamp(dt, epoch=datetime(1970,1,1)):
td = dt - epoch
# return td.total_seconds()
return (td.microseconds + (td.seconds + td.days * 86400) * 10**6) / 10**6
now = datetime.utcnow()
print now
print totimestamp(now)
Attention aux problèmes de virgule flottante.
2012-01-08 15:34:10.022403
1326036850.02
datetime
conscient en timestamp POSIXassert dt.tzinfo is not None and dt.utcoffset() is not None
timestamp = dt.timestamp() # Python 3.3+
Sur Python 3 :
from datetime import datetime, timedelta, timezone
epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)
timestamp = (dt - epoch) / timedelta(seconds=1)
integer_timestamp = (dt - epoch) // timedelta(seconds=1)
Sur Python 2 :
# utc time = local time - utc offset
utc_naive = dt.replace(tzinfo=None) - dt.utcoffset()
timestamp = (utc_naive - datetime(1970, 1, 1)).total_seconds()
Vous essayez de convertir une date en un horodatage, mais comme une date couvre une période de 24 heures, il n'y a pas un seul horodatage qui représente cette date. Je suppose que vous voulez représenter l'horodatage de cette date à minuit (00:00:00.000).
Assomption 2: La date que vous présentez n'est pas associée à un fuseau horaire particulier, mais vous voulez déterminer le décalage par rapport à un fuseau horaire particulier (UTC). Sans connaître le fuseau horaire dans lequel se trouve la date, il n’est pas possible de calculer un horodatage pour un fuseau horaire spécifique. Je suppose que vous souhaitez traiter la date comme si elle se trouvait dans le fuseau horaire du système local.
Tout d'abord, vous pouvez convertir l'instance de date en un tuple représentant les différentes composantes temporelles à l'aide du membre timetuple()
:
dtt = d.timetuple() # time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)
Vous pouvez ensuite le convertir en un timestamp en utilisant time.mktime
:
ts = time.mktime(dtt) # 1293868800.0
Vous pouvez vérifier cette méthode en la testant avec le temps d'époque lui-même (1970-01-01), auquel cas la fonction devrait retourner le décalage du fuseau horaire local à cette date :
d = datetime.date(1970,1,1)
dtt = d.timetuple() # time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=-1)
ts = time.mktime(dtt) # 28800.0
28800.0
correspond à 8 heures, ce qui serait correct pour le fuseau horaire du Pacifique (où je me trouve).
Une chaîne de temps complète contient :
[+HHMM ou -HHMM]
Par exemple :
1970-01-01 06:00:00 +0500
== 1970-01-01 01:00:00 +0000
== Historique UNIX:3600
$ python3
>>> from datetime import datetime
>>> from calendar import timegm
>>> tm = '1970-01-01 06:00:00 +0500'
>>> fmt = '%Y-%m-%d %H:%M:%S %z'
>>> timegm(datetime.strptime(tm, fmt).utctimetuple())
3600
Note:
Historique UNIX
est un nombre à virgule flottante exprimé en secondes depuis l'époque, en UTC.
Edit:
$ python3
>>> from datetime import datetime, timezone, timedelta
>>> from calendar import timegm
>>> dt = datetime(1970, 1, 1, 6, 0)
>>> tz = timezone(timedelta(hours=5))
>>> timegm(dt.replace(tzinfo=tz).utctimetuple())
3600