Je veux créer une liste de dates, commençant aujourd'hui, et remontant d'un nombre arbitraire de jours, disons, dans mon exemple, 100 jours. Y a-t-il une meilleure façon de le faire que cela?
import datetime
a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
dateList.append(a - datetime.timedelta(days = x))
print dateList
Un peu mieux ...
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(0, numdays)]
Pandas
convient parfaitement aux séries chronologiques et prend en charge directement les plages de dates.
Par exemple, pd.date_range()
:
import pandas as pd
datelist = pd.date_range(pd.datetime.today(), periods=100).tolist()
Il a également beaucoup d'options pour vous rendre la vie plus facile. Par exemple, si vous ne voulez que les jours de semaine, vous devez simplement échanger bdate_range
.
Voir http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps
De plus, il prend pleinement en charge les fuseaux horaires Pytz et peut s’étendre sans heurts entre les changements DST printemps/automne.
Obtenir une plage de dates entre les dates de début et de fin spécifiées (optimisées pour la complexité spatio-temporelle):
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")
Vous pouvez écrire une fonction génératrice qui renvoie des objets de date à partir d’aujourd’hui:
import datetime
def date_generator():
from_date = datetime.datetime.today()
while True:
yield from_date
from_date = from_date - datetime.timedelta(days=1)
Ce générateur renvoie les dates à partir d’aujourd’hui et recule d’un jour à l’autre. Voici comment prendre les 3 premières dates:
>>> 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)]
L'avantage de cette approche par rapport à une lecture en boucle ou en liste est que vous pouvez revenir autant de fois que vous le souhaitez.
Modifier
Une version plus compacte utilisant une expression génératrice à la place d'une fonction:
date_generator = (datetime.datetime.today() - datetime.timedelta(days=i) for i in itertools.count())
Usage:
>>> 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)]
Vous pouvez également utiliser l'ordinal du jour pour simplifier les choses:
def date_range(start_date, end_date):
for ordinal in range(start_date.toordinal(), end_date.toordinal()):
yield datetime.date.fromordinal(ordinal)
Ou, comme suggéré dans les commentaires, vous pouvez créer une liste comme celle-ci:
date_range = [
datetime.date.fromordinal(ordinal)
for ordinal in range(
start_date.toordinal(),
end_date.toordinal(),
)
]
oui, réinventer la roue ...... il suffit de rechercher le forum et vous obtiendrez quelque chose comme ceci:
from dateutil import rrule
from datetime import datetime
list(rrule.rrule(rrule.DAILY,count=100,dtstart=datetime.now()))
D'après le titre de cette question, je m'attendais à trouver quelque chose comme range()
, qui me permettrait de spécifier deux dates et de créer une liste avec toutes les dates entre les deux. De cette façon, il n'est pas nécessaire de calculer le nombre de jours entre ces deux dates, si on ne le sait pas à l'avance.
Donc, avec le risque d'être légèrement hors sujet, ce one-line fait le travail:
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))]
Tous les crédits à cette réponse !
Je connais un peu votre réponse, mais je viens d'avoir le même problème et j'ai décidé que la fonction d'intervalle interne de Python manquait un peu à cet égard; je l'ai donc remplacée dans un de mes modules util.
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))
Voici Gist que j'ai créé, à partir de mon propre code, cela pourrait aider. (Je sais que la question est trop ancienne, mais d'autres peuvent l'utiliser.)
https://Gist.github.com/2287345
(même chose ci-dessous)
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
Voici une ligne pour que les scripts bash obtiennent une liste des jours de la semaine. Il s’agit de python 3. Facilement modifié, peu importe l’int, le int à la fin est le nombre de jours que vous souhaitez.
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
Voici une variante pour fournir une date de début (ou plutôt de fin)
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
Voici une variante pour des dates de début et de fin arbitraires. pas que ce soit pas très efficace, mais c'est bien pour mettre dans une boucle for dans un script 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
Voici une réponse légèrement différente de la réponse de S.Lott, qui donne une liste des dates entre deux dates start
et end
. Dans l'exemple ci-dessous, du début de 2017 à aujourd'hui.
start = datetime.datetime(2017,1,1)
end = datetime.datetime.today()
daterange = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]
Lié à Matplotlib
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)
S'il y a deux dates et que vous avez besoin de la plage, essayez
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)))
Je sais que la réponse à cette question a été trouvée, mais je vais la poser pour des raisons historiques et, à mon avis, elle est simple.
import numpy as np
import datetime as dt
listOfDates=[date for date in np.arange(firstDate,lastDate,dt.timedelta(days=x))]
Bien sûr, il ne gagnera rien comme le code-golf, mais je pense que c'est élégant.
Sur la base des réponses que j'ai écrites moi-même ceci:
import datetime;
print [(datetime.date.today() - datetime.timedelta(days=x)).strftime('%Y-%m-%d') for x in range(-5, 0)]
Sortie:
['2017-12-11', '2017-12-10', '2017-12-09', '2017-12-08', '2017-12-07']
La différence est que je reçois l'objet 'date
', pas celui 'datetime.datetime
'.
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
Un générateur de plage de dates mensuel avec datetime
et dateutil
. Simple et facile à comprendre:
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)
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()