it-swarm.com.de

Erstellen eines Datumsbereichs in Python

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
237
Thomas Browne

Etwas besser ...

base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(0, numdays)]
344
S.Lott

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.

166
fantabolous

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")
48
Sandeep

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)]
40
Ayman Hourieh

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(),
    )
]
31
Hosane

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()))
29
BOFH

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

15
snake_charmer

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))
7
Rob Young

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
5
roopesh

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
4
Tim P

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)]
4
Derek Powell

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)
3
milton

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)))
3
Nelu

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.

2

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 '.

2
wmlynarski
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
1
xmduhan

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)
1
aysa
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()
0
Sasmita