from - strftime python
Creando un rango de fechas en Python (18)
Aquí está la esencia que he creado, a partir de mi propio código, esto podría ayudar. (Sé que la pregunta es demasiado antigua, pero otros pueden usarla)
https://gist.github.com/2287345
(lo mismo abajo)
import datetime
from time import mktime
def convert_date_to_datetime(date_object):
date_tuple = date_object.timetuple()
date_timestamp = mktime(date_tuple)
return datetime.datetime.fromtimestamp(date_timestamp)
def date_range(how_many=7):
for x in range(0, how_many):
some_date = datetime.datetime.today() - datetime.timedelta(days=x)
some_datetime = convert_date_to_datetime(some_date.date())
yield some_datetime
def pick_two_dates(how_many=7):
a = b = convert_date_to_datetime(datetime.datetime.now().date())
for each_date in date_range(how_many):
b = a
a = each_date
if a == b:
continue
yield b, a
Quiero crear una lista de fechas, comenzando hoy, y retrocediendo un número arbitrario de días, por ejemplo, en mi ejemplo 100 días. ¿Hay una mejor manera de hacerlo que esta?
import datetime
a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
dateList.append(a - datetime.timedelta(days = x))
print dateList
Aquí hay una línea para los scripts de bash para obtener una lista de días de la semana, esto es Python 3. Fácilmente modificado para lo que sea, el int al final es la cantidad de días en el pasado que desea.
python -c "import sys,datetime; print(''/n''.join([(datetime.datetime.today() - datetime.timedelta(days=x)).strftime(/"%Y/%m/%d/") for x in range(0,int(sys.argv[1])) if (datetime.datetime.today() - datetime.timedelta(days=x)).isoweekday()<6]))" 10
Aquí hay una variante para proporcionar una fecha de inicio (o más bien, de finalización)
python -c "import sys,datetime; print(''/n''.join([(datetime.datetime.strptime(sys.argv[1],/"%Y/%m/%d/") - datetime.timedelta(days=x)).strftime(/"%Y/%m/%d /") for x in range(0,int(sys.argv[2])) if (datetime.datetime.today() - datetime.timedelta(days=x)).isoweekday()<6]))" 2015/12/30 10
Aquí hay una variante para las fechas de inicio y finalización arbitrarias. no es que esto no sea muy eficiente, pero es bueno para poner un bucle for en un script de bash:
python -c "import sys,datetime; print(''/n''.join([(datetime.datetime.strptime(sys.argv[1],/"%Y/%m/%d/") + datetime.timedelta(days=x)).strftime(/"%Y/%m/%d/") for x in range(0,int((datetime.datetime.strptime(sys.argv[2], /"%Y/%m/%d/") - datetime.datetime.strptime(sys.argv[1], /"%Y/%m/%d/")).days)) if (datetime.datetime.strptime(sys.argv[1], /"%Y/%m/%d/") + datetime.timedelta(days=x)).isoweekday()<6]))" 2015/12/15 2015/12/30
Aquí hay una respuesta ligeramente diferente a partir de la respuesta de S.Lott que da una lista de fechas entre dos fechas de start
y end
. En el siguiente ejemplo, desde el inicio de 2017 hasta hoy.
start = datetime.datetime(2017,1,1)
end = datetime.datetime.today()
daterange = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]
Basándome en las respuestas, escribí para mí esto:
import datetime;
print [(datetime.date.today() - datetime.timedelta(days=x)).strftime(''%Y-%m-%d'') for x in range(-5, 0)]
Salida:
[''2017-12-11'', ''2017-12-10'', ''2017-12-09'', ''2017-12-08'', ''2017-12-07'']
La diferencia es que obtengo el objeto '' date
'', no el '' datetime.datetime
''.
Del título de esta pregunta esperaba encontrar algo como range()
, que me permitiera especificar dos fechas y crear una lista con todas las fechas intermedias. De esa manera, uno no necesita calcular el número de días entre esas dos fechas, si uno no lo sabe de antemano.
Entonces, con el riesgo de ser un poco fuera de tema, esta frase hace el trabajo:
import datetime
start_date = datetime.date(2011, 01, 01)
end_date = datetime.date(2014, 01, 01)
dates_2011_2013 = [ start_date + datetime.timedelta(n) for n in range(int ((end_date - start_date).days))]
Todos los créditos a esta respuesta !
Marginalmente mejor ...
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(0, numdays)]
Matplotlib relacionado
from matplotlib.dates import drange
import datetime
base = datetime.date.today()
end = base + datetime.timedelta(days=100)
delta = datetime.timedelta(days=1)
l = drange(base, end, delta)
Obtenga el rango de fechas entre la fecha de inicio y finalización especificadas (optimizado para la complejidad del tiempo y el espacio):
import datetime
start = datetime.datetime.strptime("21-06-2014", "%d-%m-%Y")
end = datetime.datetime.strptime("07-07-2014", "%d-%m-%Y")
date_generated = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]
for date in date_generated:
print date.strftime("%d-%m-%Y")
Puede escribir una función de generador que devuelva objetos de fecha a partir de hoy:
import datetime
def date_generator():
from_date = datetime.datetime.today()
while True:
yield from_date
from_date = from_date - datetime.timedelta(days=1)
Este generador devuelve fechas a partir de hoy y retrocediendo un día a la vez. Aquí es cómo tomar las primeras 3 fechas:
>>> import itertools
>>> dates = itertools.islice(date_generator(), 3)
>>> list(dates)
[datetime.datetime(2009, 6, 14, 19, 12, 21, 703890), datetime.datetime(2009, 6, 13, 19, 12, 21, 703890), datetime.datetime(2009, 6, 12, 19, 12, 21, 703890)]
La ventaja de este enfoque sobre la comprensión de un bucle o de una lista es que puede volver tantas veces como desee.
Editar
Una versión más compacta que usa una expresión generadora en lugar de una función:
date_generator = (datetime.datetime.today() - datetime.timedelta(days=i) for i in itertools.count())
Uso:
>>> dates = itertools.islice(date_generator, 3)
>>> list(dates)
[datetime.datetime(2009, 6, 15, 1, 32, 37, 286765), datetime.datetime(2009, 6, 14, 1, 32, 37, 286836), datetime.datetime(2009, 6, 13, 1, 32, 37, 286859)]
Sé que esto ha sido respondido, pero dejaré mi respuesta con propósitos históricos, y ya que creo que es sencillo.
import numpy as np
import datetime as dt
listOfDates=[date for date in np.arange(firstDate,lastDate,dt.timedelta(days=x))]
Claro que no ganará nada como el código de golf, pero creo que es elegante.
Sí, reinvente la rueda ... solo busque en el foro y obtendrá algo como esto:
from dateutil import rrule
from datetime import datetime
list(rrule.rrule(rrule.DAILY,count=100,dtstart=datetime.now()))
Si hay dos fechas y necesitas el rango prueba.
from dateutil import rrule, parser
date1 = ''1995-01-01''
date2 = ''1995-02-28''
datesx = list(rrule.rrule(rrule.DAILY, dtstart=parser.parse(date1), until=parser.parse(date2)))
También puedes usar el ordinal del día para hacerlo más simple:
def date_range(start_date, end_date):
for ordinal in range(start_date.toordinal(), end_date.toordinal()):
yield datetime.date.fromordinal(ordinal)
O como se sugiere en los comentarios, puede crear una lista como esta:
date_range = [
datetime.date.fromordinal(ordinal)
for ordinal in range(
start_date.toordinal(),
end_date.toordinal(),
)
]
Un generador de rangos de fechas mensuales con datetime
y dateutil
. Simple y fácil de entender:
import datetime as dt
from dateutil.relativedelta import relativedelta
def month_range(start_date, n_months):
for m in range(n_months):
yield start_date + relativedelta(months=+m)
Una respuesta tardía, lo sé, pero tuve el mismo problema y decidí que faltaba un poco la función de rango interno de Python a este respecto, así que la anulé en un módulo util mío.
from __builtin__ import range as _range
from datetime import datetime, timedelta
def range(*args):
if len(args) != 3:
return _range(*args)
start, stop, step = args
if start < stop:
cmp = lambda a, b: a < b
inc = lambda a: a + step
else:
cmp = lambda a, b: a > b
inc = lambda a: a - step
output = [start]
while cmp(start, stop):
start = inc(start)
output.append(start)
return output
print range(datetime(2011, 5, 1), datetime(2011, 10, 1), timedelta(days=30))
Pandas
es ideal para series de tiempo en general y tiene soporte directo para rangos de fechas.
Por ejemplo pd.date_range()
:
import pandas as pd
datelist = pd.date_range(pd.datetime.today(), periods=100).tolist()
También tiene muchas opciones para hacer la vida más fácil. Por ejemplo, si solo deseaba entre semana, solo intercambiaría bdate_range
.
Consulte http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps
Además, es totalmente compatible con las zonas horarias de pytz y puede abarcar sin problemas los cambios de horario de verano de primavera / otoño.
from datetime import datetime, timedelta
from dateutil import parser
def getDateRange(begin, end):
""" """
beginDate = parser.parse(begin)
endDate = parser.parse(end)
delta = endDate-beginDate
numdays = delta.days + 1
dayList = [datetime.strftime(beginDate + timedelta(days=x), ''%Y%m%d'') for x in range(0, numdays)]
return dayList
import datetime
def date_generator():
cur = base = datetime.date.today()
end = base + datetime.timedelta(days=100)
delta = datetime.timedelta(days=1)
while(end>base):
base = base+delta
print base
date_generator()