today parse example biblioteca python list datetime date period

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