Ich möchte eine Liste von Datumsangaben erstellen, beginnend mit dem heutigen Tag und eine beliebige Anzahl von Tagen zurückgehen, beispielsweise in meinem Beispiel 100 Tage. Gibt es einen besseren Weg, als dies zu tun?
import datetime
a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
dateList.append(a - datetime.timedelta(days = x))
print dateList
Etwas besser ...
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(0, numdays)]
Pandas
ist ideal für Zeitreihen im Allgemeinen und hat direkte Unterstützung für Datumsbereiche.
Zum Beispiel pd.date_range()
:
import pandas as pd
datelist = pd.date_range(pd.datetime.today(), periods=100).tolist()
Es hat auch viele Optionen, um das Leben leichter zu machen. Wenn Sie beispielsweise nur Wochentage haben möchten, tauschen Sie einfach bdate_range
ein.
Siehe http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps
Darüber hinaus unterstützt es pytz-Zeitzonen vollständig und kann die DST-Schicht zwischen Frühling und Herbst problemlos überspannen.
Ermitteln Sie einen Datumsbereich zwischen dem angegebenen Start- und Enddatum (für Zeit- und Raumkomplexität optimiert):
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")
Sie können eine Generatorfunktion schreiben, die Datumsobjekte ab heute zurückgibt:
import datetime
def date_generator():
from_date = datetime.datetime.today()
while True:
yield from_date
from_date = from_date - datetime.timedelta(days=1)
Dieser Generator gibt Datumsangaben ab heute zurück und rückt jeweils einen Tag zurück. So nehmen Sie die ersten 3 Termine vor:
>>> 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)]
Der Vorteil dieses Ansatzes gegenüber einem Schleifen- oder Listenverständnis besteht darin, dass Sie so oft zurückgehen können, wie Sie möchten.
Bearbeiten
Eine kompaktere Version, die einen Generatorausdruck anstelle einer Funktion verwendet:
date_generator = (datetime.datetime.today() - datetime.timedelta(days=i) for i in itertools.count())
Verwendungszweck:
>>> 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)]
Sie können die Tagesordnungszahl auch verwenden, um es einfacher zu machen:
def date_range(start_date, end_date):
for ordinal in range(start_date.toordinal(), end_date.toordinal()):
yield datetime.date.fromordinal(ordinal)
Oder wie in den Kommentaren vorgeschlagen, können Sie eine Liste wie folgt erstellen:
date_range = [
datetime.date.fromordinal(ordinal)
for ordinal in range(
start_date.toordinal(),
end_date.toordinal(),
)
]
ja, das Rad neu erfinden .... Durchsuchen Sie das Forum.
from dateutil import rrule
from datetime import datetime
list(rrule.rrule(rrule.DAILY,count=100,dtstart=datetime.now()))
Vom Titel dieser Frage aus erwartete ich etwas wie range()
, mit dem ich zwei Datumsangaben angeben und eine Liste mit allen dazwischen liegenden Datumsangaben erstellen könnte. Auf diese Weise muss man nicht die Anzahl der Tage zwischen diesen beiden Daten berechnen, wenn man sie nicht vorher kennt.
Dieser One-Liner erledigt also mit dem Risiko, ein wenig vom Thema abzulenken, die Aufgabe:
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))]
Alle Credits zu dieser Antwort !
Ich weiß, eine späte Antwort, aber ich hatte nur das gleiche Problem und entschied, dass die interne Range-Funktion von Python in dieser Hinsicht etwas fehlte, also habe ich sie in einem meiner Funktionsmodule überschrieben.
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))
Hier ist Gist, den ich aus meinem eigenen Code erstellt habe, dies könnte helfen. (Ich weiß, die Frage ist zu alt, aber andere können sie verwenden.)
https://Gist.github.com/2287345
(das gleiche unten)
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
Hier ist ein One-Liner für Bash-Skripte, um eine Liste der Wochentage zu erhalten, dies ist Python 3. Leicht geändert für was auch immer, das Int am Ende ist die Anzahl der Tage in der Vergangenheit, die Sie wünschen.
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
Hier ist eine Variante, um ein Anfangs- oder Enddatum anzugeben
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
Hier ist eine Variante für beliebige Start- und Enddaten. Nicht, dass dies nicht besonders effizient ist, aber gut für das Einfügen einer for-Schleife in einem Bash-Skript ist:
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
Hier ist eine etwas andere Antwort, die auf der Antwort von S.Lott aufbaut, die eine Liste von Datumsangaben zwischen zwei Datumsangaben start
und end
enthält. Im Beispiel unten von Anfang 2017 bis heute.
start = datetime.datetime(2017,1,1)
end = datetime.datetime.today()
daterange = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]
Matplotlib verwandt
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)
Wenn es zwei Termine gibt und Sie den Bereich benötigen, versuchen Sie es
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)))
Ich weiß, dass dies beantwortet wurde, aber ich werde meine Antwort aus historischen Gründen niederlegen.
import numpy as np
import datetime as dt
listOfDates=[date for date in np.arange(firstDate,lastDate,dt.timedelta(days=x))]
Sicher gewinnt es nichts wie Code-Golf, aber ich denke, es ist elegant.
Basierend auf Antworten, die ich für mich selbst geschrieben habe:
import datetime;
print [(datetime.date.today() - datetime.timedelta(days=x)).strftime('%Y-%m-%d') for x in range(-5, 0)]
Ausgabe:
['2017-12-11', '2017-12-10', '2017-12-09', '2017-12-08', '2017-12-07']
Der Unterschied ist, dass ich das 'date
'-Objekt bekomme, nicht das' 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
Ein monatlicher Datumsbereichsgenerator mit datetime
und dateutil
. Einfach und leicht verständlich:
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()