Convertir la date de chaîne en horodatage en Python

219

Comment convertir une chaîne au format "%d/%m/%Y"horodatage?

"01/12/2011" -> 1322697600
Shankar Cabus
la source
Quel est le 2ème numéro? Unix Epoch time?
Hasteur
4
@Hasteur, oui. Le deuxième nombre représente le nombre de secondes qui se sont écoulées entre le début de l'époque unix et la date spécifiée. Ce format est également appelé heure POSIX.
eikonomega

Réponses:

316
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
Katriel
la source
10
il suppose minuit 01/12/2011 dans le fuseau horaire local. Si l'entrée est en UTC; vous pouvez utiliser calendar.timegm()ou.toordinal()
jfs
49
datetime.datetime.strptime(s, "%d/%m/%Y").timestamp()est un peu plus court
timdiels
11
@timdiels: encore une fois. .timestamp()suppose l' heure locale au lieu de l'UTC si aucun fuseau horaire explicite n'est donné. Le code dans la réponse ne fonctionne (produit attendu 1322697600) que sur un ordinateur où le fuseau horaire local n'a aucun décalage utc.
jfs
7
cela ne fonctionne pas: datetime.datetime.strptime ("2014: 06: 28 11:53:21", "% Y:% m:% d% H:% M:% S"). timestamp () Traceback ( dernier appel le plus récent): Fichier "<stdin>", ligne 1, dans <module> AttributeError: l'objet 'datetime.datetime' n'a pas d'attribut 'timestamp'
Zdenek Maxa
5
@ZdenekMaxa datetime.timestamp () disponible uniquement pour les versions python> = 3.3. docs.python.org/3/whatsnew/3.3.html
joni jones
48

J'utilise ciso8601, ce qui est 62x plus rapide que le strptime de datetime.

t = "01/12/2011"
ts = ciso8601.parse_datetime(t)
# to get time in seconds:
time.mktime(ts.timetuple())

Vous pouvez en savoir plus ici .

Eyal Ch
la source
2
c'est une suggestion fantastique. Je viens de l'utiliser et j'ai rasé des tonnes de temps de mon exécution.
David
3
Mon dieu c'est rapide
Hews
3
Et +1 pour ne pas avoir besoin de moi pour préciser le format de la chaîne de temps.
gowenfawr
40

Pour convertir la chaîne en un objet date:

from datetime import date, datetime

date_string = "01/12/2011"
date_object = date(*map(int, reversed(date_string.split("/"))))
assert date_object == datetime.strptime(date_string, "%d/%m/%Y").date()

La façon de convertir l'objet date en horodatage POSIX dépend du fuseau horaire. De la conversion datetime.dateen horodatage UTC en Python :

  • l'objet date représente minuit en UTC

    import calendar
    
    timestamp1 = calendar.timegm(utc_date.timetuple())
    timestamp2 = (utc_date.toordinal() - date(1970, 1, 1).toordinal()) * 24*60*60
    assert timestamp1 == timestamp2
  • l'objet date représente minuit dans l'heure locale

    import time
    
    timestamp3 = time.mktime(local_date.timetuple())
    assert timestamp3 != timestamp1 or (time.gmtime() == time.localtime())

Les horodatages sont différents sauf si minuit en UTC et en heure locale est la même instance de temps.

jfs
la source
Quand je lance les exemples dans ce post, je reçois l'erreur: NameError: name 'wckCalendar' is not defined. J'exécute Python 3.4.1 sur une machine Windows 32 bits. Une idée? Merci.
sedeh
1
@sedeh il n'y a pas de wckCalendar dans le post. Vérifiez votre code.
jfs
@JFSebastian Exactement, et je n'essayais pas d'appeler directement wckCalendar. Il apparaît simplement dans le message d'erreur. Voir mon article ici discutant du problème.
sedeh
1
@ törzsmókus: Si la réponse est fausse, peu importe à quel point elle est lisible.
jfs
1
@ törzsmókus: regardez ma réponse: elle peut produire deux nombres différents. Votre réponse produit un numéro sans mentionner lequel.
jfs
21

La réponse dépend également de votre fuseau horaire de date d'entrée. Si votre date est une date locale, vous pouvez utiliser mktime () comme l'a dit katrielalex - seulement je ne vois pas pourquoi il a utilisé datetime au lieu de cette version plus courte:

>>> time.mktime(time.strptime('01/12/2011', "%d/%m/%Y"))
1322694000.0

Mais observez que mon résultat est différent du sien, car je suis probablement dans un TZ différent (et le résultat est un horodatage UNIX sans fuseau horaire)

Maintenant, si la date d'entrée est déjà en UTC, je pense que la bonne solution est:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600
Nowakus
la source
Je pense que c'est mieux. Pas besoin d'importer à la fois 'time' et 'datetime'.
kennyut
17

Utilisez simplement datetime.datetime.strptime:

import datetime
stime = "01/12/2011"
print(datetime.datetime.strptime(stime, "%d/%m/%Y").timestamp())

Résultat:

1322697600

Pour utiliser UTC au lieu du fuseau horaire local, utilisez .replace:

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()
nm111
la source
Pour une réponse complète, vous devez dire qu'il n'est valable que pour python 3.3+
Eduardo
Sur le premier exemple, le résultat est un floatnonint
CONvid19
6

Vous devez d' abord la classe strptime pour convertir la chaîne au format struct_time.

Ensuite, utilisez mktime à partir de là pour obtenir votre flotteur.

Cryptite
la source
6

Beaucoup de ces réponses ne prennent pas la peine de considérer que la date est naïve pour commencer

Pour être correct, vous devez d'abord faire de la date naïve une date / heure sensible au fuseau horaire

import datetime
import pytz
# naive datetime
d = datetime.datetime.strptime('01/12/2011', '%d/%m/%Y')
>>> datetime.datetime(2011, 12, 1, 0, 0)

# add proper timezone
pst = pytz.timezone('America/Los_Angeles')
d = pst.localize(d)
>>> datetime.datetime(2011, 12, 1, 0, 0,
tzinfo=<DstTzInfo 'America/Los_Angeles' PST-1 day, 16:00:00 STD>)

# convert to UTC timezone
utc = pytz.UTC
d = d.astimezone(utc)
>>> datetime.datetime(2011, 12, 1, 8, 0, tzinfo=<UTC>)

# epoch is the beginning of time in the UTC timestamp world
epoch = datetime.datetime(1970,1,1,0,0,0,tzinfo=pytz.UTC)
>>> datetime.datetime(1970, 1, 1, 0, 0, tzinfo=<UTC>)

# get the total second difference
ts = (d - epoch).total_seconds()
>>> 1322726400.0

Aussi:

Soyez prudent, utilisez pytzfor tzinfodans un datetime.datetimeNE FONCTIONNE PAS pour de nombreux fuseaux horaires. Voir datetime avec le fuseau horaire pytz. Offset différent selon la configuration de tzinfo

# Don't do this:
d = datetime.datetime(2011, 12, 1,0,0,0, tzinfo=pytz.timezone('America/Los_Angeles'))
>>> datetime.datetime(2011, 1, 12, 0, 0, 
tzinfo=<DstTzInfo 'America/Los_Angeles' LMT-1 day, 16:07:00 STD>)
# tzinfo in not PST but LMT here, with a 7min offset !!!

# when converting to UTC:
d = d.astimezone(pytz.UTC)
>>> datetime.datetime(2011, 1, 12, 7, 53, tzinfo=<UTC>)
# you end up with an offset

https://en.wikipedia.org/wiki/Local_mean_time

MrE
la source
6

Je suggérerais dateutil :

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()
törzsmókus
la source
Il est faux. OP attend l'heure en "%d/%m/%Y"format. Comparer: dateutil.parser.parse("01/02/2001")etdatetime.strptime("01/02/2001", "%d/%m/%Y")
jfs
merci @jfs, bonne capture. J'ai mis à jour ma réponse en conséquence. (en tant que non-américain, je n'aurais pas pensé que le format illogique M / D / Y était la valeur par défaut pour l'analyseur.)
törzsmókus
1
il ne produit pas l'attendu 1322697600sauf si votre fuseau horaire local est UTC. Voir mon commentaire de 2014
jfs
4

Semble assez efficace:

import datetime
day, month, year = '01/12/2011'.split('/')
datetime.datetime(int(year), int(month), int(day)).timestamp()

1,61 µs ± 120 ns par boucle (moyenne ± écart type de 7 pistes, 100000 boucles chacune)

Gérard
la source
Quelle est la datetimefonction? datetimede la datetimebibliothèque ne prend pas en charge.timestamp()
Joooeey
@Joooeey: Oui , sur Python 3.3 ou version ultérieure . N'était pas disponible lorsque la question a été publiée, mais elle est disponible depuis septembre 2012.
ShadowRanger
0

utilisez simplement datetime.timestamp (votre instance de datetime), l'instance de datetime contient les informations de fuseau horaire, donc l'horodatage sera un horodatage utc standard. si vous transformez le datetime en horaire, il perdra son fuseau horaire, donc le résultat sera une erreur. si vous voulez fournir une interface, vous devez écrire comme ceci: int (datetime.timestamp (time_instance)) * 1000

user6689187
la source
0

vous pouvez convertir en isoformat

my_date = '2020/08/08'
my_date = my_date.replace('/','-') # just to adapte to your question
date_timestamp = datetime.datetime.fromisoformat(my_date).timestamp()
Aliens Dev
la source
-1

Une fonction simple pour obtenir l'heure UNIX Epoch.

REMARQUE : Cette fonction suppose que la date et l'heure d'entrée sont au format UTC (reportez-vous aux commentaires ici).

def utctimestamp(ts: str, DATETIME_FORMAT: str = "%d/%m/%Y"):
    import datetime, calendar
    ts = datetime.datetime.utcnow() if ts is None else datetime.datetime.strptime(ts, DATETIME_FORMAT)
    return calendar.timegm(ts.utctimetuple())

Utilisation :

>>> utctimestamp("01/12/2011")
1322697600
>>> utctimestamp("2011-12-01", "%Y-%m-%d")
1322697600
gihanchanuka
la source