2011-05-03 19 views
10

Tengo dos variables de cadena que contienen fechas en formato aaaa-mm-dd de la siguiente manera:Generación de todas las fechas dentro de un rango determinado en Python

date1 = '2011-05-03' 
date2 = '2011-05-10' 

Quiero escribir código que genera todas las fechas en el fecha1 gama hasta la fecha2. ¿Cómo se puede hacer esto en Python?

+2

duplicado http://stackoverflow.com/questions/993358/creating-a-range-of-dates-in-python –

+1

@msa Posiblemente, pero no de ese. – badp

+0

posible duplicado de [iteración a través de un rango de fechas en Python] (http://stackoverflow.com/questions/1060279/iterating-through-a-range-of-dates-in-python) – kasperd

Respuesta

2
import datetime 
real_date1 = datetime.date(*[int(x) for x in date1.split('-')]) 
real_date2 = datetime.date(*[int(x) for x in date2.split('-')]) 
date_range = real_date2 - real_date1 
dates = list() 
for days in xrange(date_range.days): 
    dates.append(real_date1 + datetime.timedelta(days)) 

print dates 
2
import time 

def dates_between(start, end): 
    start_epoch = int(time.mktime(time.strptime(start, "%Y-%m-%d"))) 
    end_epoch = int(time.mktime(time.strptime(end, "%Y-%m-%d"))) + 1 #include end 
    return range(start_epoch, end_epoch, 86400) 
+2

Esto se rompe durante días que son no tiene 86.400 segundos de duración, pero no soy Jon Skeet-y lo suficiente como para saber si esta suposición es cierta "suficientemente bien". – badp

14
from dateutil import rrule, parser 

date1 = '2011-05-03' 
date2 = '2011-05-10' 

dates = list(rrule.rrule(rrule.DAILY, 
         dtstart=parser.parse(date1), 
         until=parser.parse(date2))) 

print dates 

Desde dateutil no es una biblioteca estándar, tendrá que instalarlo como un paquete separado. Consulte la documentación para obtener más detalles sobre el formato (especialmente los conmutadores dayfirst y yearfirst).

+1

Cool. ¿Cómo sabe el analizador si es aaaa-mm-dd o aaaa-dd-mm? –

1
>>> for a in range(9): 
...  print(datetime.date(2011, 05, 03) + datetime.timedelta(a)) 
... 
2011-05-03 
2011-05-04 
2011-05-05 
2011-05-06 
2011-05-07 
2011-05-08 
2011-05-09 
2011-05-10 
2011-05-11 

No estoy muy seguro de si el análisis sintáctico de las cadenas fue integral o simplemente la forma en que comenzó la pregunta. Si es así, ignore la respuesta como simplificado

19

Las fechas se pueden comparar entre sí al igual que los números, y puede hacer cálculos matemáticos relacionados con la fecha con el objeto datetime.timedelta. No hay ninguna razón para usar dateutil aquí, y no hay ninguna razón para codificar el número de iteraciones a la 'rango (9)'. Esto realmente se vuelve similar a cómo lidiarías con números antiguos simples.

>>> import datetime 
>>> date1 = '2011-05-03' 
>>> date2 = '2011-05-10' 
>>> start = datetime.datetime.strptime(date1, '%Y-%m-%d') 
>>> end = datetime.datetime.strptime(date2, '%Y-%m-%d') 
>>> step = datetime.timedelta(days=1) 
>>> while start <= end: 
...  print start.date() 
...  start += step 
... 
2011-05-03 
2011-05-04 
2011-05-05 
2011-05-06 
2011-05-07 
2011-05-08 
2011-05-09 
2011-05-10 
>>> 
11

pandas es ideal para series de tiempo, en general, y cuenta con el apoyo directo tanto para los rangos de fechas y la fecha de análisis (que es automagic).

import pandas as pd 
date1 = '2011-05-03' 
date2 = '2011-05-10' 
mydates = pd.date_range(date1, date2).tolist() 

También tiene muchas opciones para hacer la vida más fácil. Por ejemplo, si solo desea días de la semana, simplemente cambiaría en bdate_range.

Ver http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps

3

Me gusta este porque es intuitivo y se da una serie de cadenas de fecha.

import re 
import datetime 

def datetime_to_str_date(dt): 
    return re.sub(r'\T.+$','', dt.isoformat()) 

start_date = datetime.datetime.strptime('2016-01-01', '%Y-%m-%d') 
end_date = datetime.datetime.today() 
num_of_days = (end_date - start_date).days 

date_list = map(
     datetime_to_str_date, 
     [start_date + datetime.timedelta(days=x) for x in range(0, num_of_days)] 
) 
2

Suponiendo que las fechas son ya como clase datetime.date puede utilizar .fromordinal y .toordinal para crear esta oneliner.

from datetime import date 

start_date = date(2011, 5, 3) 
end_date = date(2011, 5, 10) 

[date.fromordinal(i) for i in range(start_date.toordinal(), end_date.toordinal())] 

El resultado es exclusiva end_date. Use end_date.toordinal() + 1 para un rango que incluye end_date.

Cuestiones relacionadas