parse - python today date
Genera una lista de fechas y horas entre un intervalo (4)
Las soluciones sugeridas aquí funcionan bien para intervalos de días, horas, etc. usando timedelta
, o cualquier cosa que dateutil.relativedelta
admita si desea confiar en bibliotecas de terceros. Pero quería compartir mi solución para el caso específico de intervalos mensuales en el formato aaaamm , que se solicita here (pero marcado como duplicado de esta pregunta).
def iterate_months(start_ym, end_ym):
for ym in range(int(start_ym), int(end_ym) + 1):
if ym % 100 > 12 or ym % 100 == 0:
continue
yield str(ym)
list(iterate_months(''201710'', ''201803''))
Salida:
[''201710'', ''201711'', ''201712'', ''201801'', ''201802'', ''201803'']
Esta solución es bastante específica para esta necesidad particular de formato aaaamm (aunque aparece con frecuencia en mi mundo, al menos) y puede no ser la respuesta más eficiente con la gran cantidad de continue
, pero tiene las ventajas de ser conciso, fácil para comprender, y no implica una cantidad de bibliotecas o código de conversión de fecha.
Dado dos fechas ( start_date
y end_date
), me gustaría generar una lista de otras fechas entre estas dos fechas, las nuevas fechas están separadas por un intervalo variable. por ejemplo, cada 4 días entre 2011-10-10 y 2011-12-12 o cada 8 horas entre ahora y mañana a las 19p.m.
Tal vez algo más o menos equivalente a la clase de PHP Dateperiod .
¿Cuál sería la forma más eficiente de lograr esto en Python?
Prueba esto:
from datetime import datetime
from dateutil.relativedelta import relativedelta
def date_range(start_date, end_date, increment, period):
result = []
nxt = start_date
delta = relativedelta(**{period:increment})
while nxt <= end_date:
result.append(nxt)
nxt += delta
return result
El ejemplo en la pregunta "cada 8 horas entre hoy y mañana 19:00" se escribiría así:
start_date = datetime.now()
end_date = start_date + relativedelta(days=1)
end_date = end_date.replace(hour=19, minute=0, second=0, microsecond=0)
date_range(start_date, end_date, 8, ''hours'')
Tenga en cuenta que los valores válidos para el period
son los definidos para la información relativedelta
relativedelta, a saber: ''years'', ''months'', ''weeks'', ''days'', ''hours'', ''minutes'', ''seconds'', ''microseconds''
.
Mi solución arroja una lista , como se requiere en la pregunta. Si no necesita todos los elementos a la vez, puede usar generadores, como en la respuesta de @MartijnPieters.
Realmente me gustaron las dos respuestas de @Martijn Pieters y @ Óscar López. Permítanme sugerir mi solución combinada entre esas dos respuestas.
from datetime import date, datetime, timedelta
def datetime_range(start, end, delta):
current = start
if not isinstance(delta, timedelta):
delta = timedelta(**delta)
while current < end:
yield current
current += delta
start = datetime(2015,1,1)
end = datetime(2015,1,31)
#this unlocks the following interface:
for dt in datetime_range(start, end, {''days'': 2, ''hours'':12}):
print dt
print dt
2015-01-01 00:00:00
2015-01-03 12:00:00
2015-01-06 00:00:00
2015-01-08 12:00:00
2015-01-11 00:00:00
2015-01-13 12:00:00
2015-01-16 00:00:00
2015-01-18 12:00:00
2015-01-21 00:00:00
2015-01-23 12:00:00
2015-01-26 00:00:00
2015-01-28 12:00:00
Use datetime.timedelta
:
from datetime import date, datetime, timedelta
def perdelta(start, end, delta):
curr = start
while curr < end:
yield curr
curr += delta
>>> for result in perdelta(date(2011, 10, 10), date(2011, 12, 12), timedelta(days=4)):
... print result
...
2011-10-10
2011-10-14
2011-10-18
2011-10-22
2011-10-26
2011-10-30
2011-11-03
2011-11-07
2011-11-11
2011-11-15
2011-11-19
2011-11-23
2011-11-27
2011-12-01
2011-12-05
2011-12-09
Funciona tanto para fechas como para objetos datetime. Tu segundo ejemplo:
>>> for result in perdelta(datetime.now(),
... datetime.now().replace(hour=19) + timedelta(days=1),
... timedelta(hours=8)):
... print result
...
2012-05-21 17:25:47.668022
2012-05-22 01:25:47.668022
2012-05-22 09:25:47.668022
2012-05-22 17:25:47.668022