¿Cómo truncar la hora en un objeto DateTime en Python?
¿Cuál es una forma elegante de truncar un objeto datetime de python?
En este caso particular, al día. Así que básicamente establecer hora, minuto, segundos y microsegundos a 0.
Me gustaría que la salida también fuera un objeto datetime, no una cadena.
12 answers
Creo que esto es lo que estás buscando...
>>> dt = datetime.datetime.now()
>>> dt = dt.replace(hour=0, minute=0, second=0, microsecond=0) # Returns a copy
>>> dt
datetime.datetime(2011, 3, 29, 0, 0)
Pero si realmente no te importa el aspecto temporal de las cosas, entonces realmente solo deberías estar pasando date
objetos...
>>> d_truncated = datetime.date(dt.year, dt.month, dt.day)
>>> d_truncated
datetime.date(2011, 3, 29)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-03 21:18:29
Use un date
no un datetime
si no le importa el tiempo.
>>> now = datetime.now()
>>> now.date()
datetime.date(2011, 3, 29)
Puede actualizar una fecha y hora como esta:
>>> now.replace(minute=0, hour=0, second=0, microsecond=0)
datetime.datetime(2011, 3, 29, 0, 0)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-29 17:05:12
Cuatro años después: otro camino, evitando replace
Sé que la respuesta aceptada de hace cuatro años funciona, pero esto parece un poco más liviano que usar replace
:
dt = datetime.date.today()
dt = datetime.datetime(dt.year, dt.month, dt.day)
Notas
- Cuando se crea un objeto
datetime
sin pasar propiedades de tiempo al constructor, se obtiene midnight. - Como otros han señalado, esto supone que desea un objeto datetime para su uso posterior con timedeltas.
- Puedes, por supuesto, sustituir esto por la primera línea:
dt = datetime.datetime.now()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-02 06:44:19
No se puede truncar un objeto datetime porque es inmutable.
Sin embargo, aquí hay una manera de construir una nueva datetime con campos de 0 horas, minutos, segundos y microsegundos, sin tirar la fecha original o tzinfo:
newdatetime = now.replace(hour=0, minute=0, second=0, microsecond=0)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-01 20:10:06
Para obtener una medianoche correspondiente a un objeto datetime dado, puede usar datetime.combine()
método :
>>> from datetime import datetime, time
>>> dt = datetime.utcnow()
>>> dt.date()
datetime.date(2015, 2, 3)
>>> datetime.combine(dt, time.min)
datetime.datetime(2015, 2, 3, 0, 0)
La ventaja en comparación con el método .replace()
es que la solución basada en datetime.combine()
seguirá funcionando incluso si datetime
el módulo introduce el soporte de nanosegundos .
tzinfo
se puede conservar si es necesario, pero el desplazamiento utc puede ser diferente a medianoche, por ejemplo, debido a una transición DST y, por lo tanto, una solución ingenua (configuración del atributo tzinfo
time) puede fallar. Ver ¿Cómo obtengo la hora UTC de "medianoche" para una zona horaria determinada?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:32
Puede usar datetime.strftime para extraer el día, el mes, el año...
Ejemplo:
from datetime import datetime
d = datetime.today()
# Retrieves the day and the year
print d.strftime("%d-%Y")
Salida (para hoy):
29-2011
Si solo desea recuperar el día, puede usar el atributo day como:
from datetime import datetime
d = datetime.today()
# Retrieves the day
print d.day
Ouput (por hoy):
29
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-29 17:04:37
Podrías usar pandas para eso (aunque podría ser una sobrecarga para esa tarea). Podrías usar redondo, floor and ceil like for usual numbers and any pandas frequency from offset-alias :
import pandas as pd
import datetime as dt
now = dt.datetime.now()
pd_now = pd.Timestamp(now)
freq = '1d'
pd_round = pd_now.round(freq)
dt_round = pd_round.to_pydatetime()
print(now)
print(dt_round)
"""
2018-06-15 09:33:44.102292
2018-06-15 00:00:00
"""
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-15 12:08:51
Hay una gran biblioteca utilizada para manipular fechas: Delorean
import datetime
from delorean import Delorean
now = datetime.datetime.now()
d = Delorean(now, timezone='US/Pacific)
>>> now
datetime.datetime(2015, 3, 26, 19, 46, 40, 525703)
>>> d.truncate('second')
Delorean(datetime=2015-03-26 19:46:40-07:00, timezone=US/Pacific)
>>> d.truncate('minute')
Delorean(datetime=2015-03-26 19:46:00-07:00, timezone=US/Pacific)
>>> d.truncate('hour')
Delorean(datetime=2015-03-26 19:00:00-07:00, timezone=US/Pacific)
>>> d.truncate('day')
Delorean(datetime=2015-03-26 00:00:00-07:00, timezone=US/Pacific)
>>> d.truncate('month')
Delorean(datetime=2015-03-01 00:00:00-07:00, timezone=US/Pacific)
>>> d.truncate('year')
Delorean(datetime=2015-01-01 00:00:00-07:00, timezone=US/Pacific)
Y si desea recuperar el valor datetime:
>>> d.truncate('year').datetime
datetime.datetime(2015, 1, 1, 0, 0, tzinfo=<DstTzInfo 'US/Pacific' PDT-1 day, 17:00:00 DST>)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-27 02:54:50
Hay un módulo datetime_truncate que maneja esto para usted. Sólo llama datetime.reemplazar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-01 11:47:25
6 años después... Encontré este post y me gustó más el enfoque numpy:
import numpy as np
dates_array = np.array(['2013-01-01', '2013-01-15', '2013-01-30']).astype('datetime64[ns]')
truncated_dates = dates_array.astype('datetime64[D]')
Salud
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-25 10:47:21
Si está tratando con una Serie de tipo DateTime, hay una forma más eficiente de truncarlos, especialmente cuando el objeto Series tiene muchas filas.
Puede utilizar la función floor
Por ejemplo, si desea truncar a horas:
Generar un rango de fechas
times = pd.Series(pd.date_range(start='1/1/2018 04:00:00', end='1/1/2018 22:00:00', freq='s'))
Podemos comprobarlo comparando el tiempo de ejecución entre las funciones replace y floor.
%timeit times.apply(lambda x : x.replace(minute=0, second=0, microsecond=0))
>>> 341 ms ± 18.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit times.dt.floor('h')
>>>>2.26 ms ± 451 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-19 00:10:01
¿Qué significa truncar?
Usted tiene control total sobre el formato usando el método strftime() y usando una cadena de formato apropiada.
Http://docs.python.org/library/datetime.html#strftime-strptime-behavior
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-29 16:54:17