Convertir fecha de cadena a marca de tiempo en Python

219

¿Cómo convertir una cadena en formato "%d/%m/%Y"a marca de tiempo?

"01/12/2011" -> 1322697600
Shankar Cabus
fuente
¿Cuál es el segundo número? Unix Epoch time?
Hasteur
44
@Hasteur, sí. El segundo número representa el número de segundos que han pasado entre el comienzo de la época de Unix y la fecha especificada. Este formato también se conoce como tiempo POSIX.
eikonomega

Respuestas:

316
>>> import time
>>> import datetime
>>> s = "01/12/2011"
>>> time.mktime(datetime.datetime.strptime(s, "%d/%m/%Y").timetuple())
1322697600.0
Katriel
fuente
10
asume la medianoche 01/12/2011 en la zona horaria local. Si la entrada está en UTC; podría usar calendar.timegm()o.toordinal()
jfs
49
datetime.datetime.strptime(s, "%d/%m/%Y").timestamp()es un poco más corto
timdiels
11
@timdiels: de nuevo. .timestamp()asume la hora local en lugar de UTC si no se proporciona una zona horaria explícita. El código en la respuesta funciona (produce esperado 1322697600) solo en una computadora donde la zona horaria local tiene cero compensación de utc.
jfs
77
esto no funciona: datetime.datetime.strptime ("2014: 06: 28 11:53:21", "% Y:% m:% d% H:% M:% S"). timestamp () Traceback ( última llamada más reciente): Archivo "<stdin>", línea 1, en <module> AttributeError: el objeto 'datetime.datetime' no tiene atributo 'timestamp'
Zdenek Maxa
55
@ZdenekMaxa datetime.timestamp () disponible solo para python> = 3.3 versiones. docs.python.org/3/whatsnew/3.3.html
joni jones
48

Yo uso ciso8601, que es 62 veces más rápido que el strptime de datetime.

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

Puedes aprender más aquí .

Eyal Ch
fuente
2
Esta es una sugerencia fantástica. Simplemente lo usé y ahorré TONELADAS de tiempo de mi ejecución.
David
3
Mi Dios, esto es rápido
Talas
3
Y +1 por no necesitar que explique cuál es el formato de la cadena de tiempo.
gowenfawr
40

Para convertir la cadena en un objeto de fecha:

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 forma de convertir el objeto de fecha en la marca de tiempo POSIX depende de la zona horaria. De convertir datetime.datea marca de tiempo UTC en Python :

  • el objeto de fecha representa la medianoche 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
  • el objeto de fecha representa la medianoche en hora local

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

Las marcas de tiempo son diferentes a menos que la medianoche en UTC y en la hora local sea la misma instancia de hora.

jfs
fuente
Cuando ejecuto los ejemplos de este post, me sale el error: NameError: name 'wckCalendar' is not defined. Estoy ejecutando Python 3.4.1 en una máquina con Windows de 32 bits. ¿Alguna idea? Gracias.
sedeh
1
@sedeh no hay wckCalendar en la publicación. Revisa tu código.
jfs
@JFSebastian Exactamente, y no estaba tratando de llamar a wckCalendar directamente. Simplemente aparece en el mensaje de error. Vea mi publicación aquí discutiendo el problema.
sedeh
1
@ törzsmókus: Si la respuesta es incorrecta, no importa cuán legible sea.
jfs
1
@ törzsmókus: mira mi respuesta: puede producir dos números diferentes. Su respuesta produce un número sin mencionar cuál.
jfs
21

La respuesta también depende de la zona horaria de la fecha de entrada. Si su fecha es una fecha local, entonces puede usar mktime () como dijo katrielalex, solo que no veo por qué usó datetime en lugar de esta versión más corta:

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

Pero observe que mi resultado es diferente al suyo, ya que probablemente estoy en una TZ diferente (y el resultado es la marca de tiempo UNIX sin zona horaria)

Ahora, si la fecha de entrada ya está en UTC, creo que la solución correcta es:

>>> calendar.timegm(time.strptime('01/12/2011', '%d/%m/%Y'))
1322697600
Nowakus
fuente
Creo que esto es mejor. No es necesario importar tanto "hora" como "fecha y hora".
kennyut
17

Simplemente use datetime.datetime.strptime:

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

Resultado:

1322697600

Para usar UTC en lugar del uso de la zona horaria local .replace:

datetime.datetime.strptime(stime, "%d/%m/%Y").replace(tzinfo=datetime.timezone.utc).timestamp()
nm111
fuente
Para una respuesta completa, debe decir que solo es válido para Python 3.3+
Eduardo
En el primer ejemplo, el resultado es un floatnoint
CONvid19
6

Primero debe la clase strptime para convertir la cadena a un formato struct_time.

Luego solo usa mktime desde allí para obtener tu flotador.

Cripta
fuente
6

Muchas de estas respuestas no se molestan en considerar que la fecha es ingenua para empezar

Para ser correcto, primero debe hacer que la fecha ingenua sea una fecha y hora consciente de la zona horaria

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

También:

Tenga cuidado, utilizando pytzpara tzinfoen un datetime.datetimetrabajo no para muchas zonas horarias. Vea datetime con la zona horaria pytz. Diferente desplazamiento dependiendo de cómo se configure 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
fuente
6

Sugeriría dateutil :

import dateutil.parser
dateutil.parser.parse("01/12/2011", dayfirst=True).timestamp()
törzsmókus
fuente
Está mal. OP espera tiempo en "%d/%m/%Y"formato. Comparar: dateutil.parser.parse("01/02/2001")ydatetime.strptime("01/02/2001", "%d/%m/%Y")
jfs
gracias @jfs, buena captura. Actualicé mi respuesta en consecuencia. (como no estadounidense, no habría pensado que el formato ilógico M / D / Y era el predeterminado para el analizador sintáctico).
törzsmókus
1
no produce lo esperado a 1322697600menos que su zona horaria local sea UTC. Ver mi comentario de 2014
jfs
4

Parece ser bastante eficiente:

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

1.61 µs ± 120 ns por bucle (media ± desviación estándar de 7 corridas, 100000 bucles cada una)

Gerard
fuente
¿Cuál es la datetimefunción? datetimede la datetimebiblioteca no es compatible.timestamp()
Joooeey
@Joooeey: Sí, en Python 3.3 o posterior . No estaba disponible cuando se publicó la pregunta, pero ha estado disponible desde septiembre de 2012.
ShadowRanger
0

solo use datetime.timestamp (su fecha datetime), la instancia de datetime contiene la información de la zona horaria, por lo que la marca de tiempo será una marca de tiempo utc estándar. Si transforma la fecha y la hora en tupla de tiempo, perderá su zona horaria, por lo que el resultado será un error. si desea proporcionar una interfaz, debe escribir así: int (datetime.timestamp (time_instance)) * 1000

usuario6689187
fuente
0

puedes convertir a 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
fuente
-1

Una función simple para obtener el tiempo de UNIX Epoch.

NOTA : Esta función supone que la fecha y hora de entrada está en formato UTC (consulte los comentarios aquí).

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

Uso :

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