web-dev-qa-db-ja.com

Pythonで日付範囲を作成する

今日から始めて、任意の日数、たとえば私の例では100日前に戻って、日付のリストを作成したいと思います。これよりも良い方法はありますか?

import datetime

a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
    dateList.append(a - datetime.timedelta(days = x))
print dateList
268
Thomas Browne

やや優れている...

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

Pandas は一般に時系列に最適で、日付範囲を直接サポートします。

例えば pd.date_range()

import pandas as pd
datelist = pd.date_range(pd.datetime.today(), periods=100).tolist()

人生を楽にするための選択肢もたくさんあります。たとえば、平日だけが必要な場合は、 bdate_range を入れ替えるだけです。

http://pandas.pydata.org/pandas-docs/stable/timeseries.html#generating-ranges-of-timestamps を参照してください。

さらに、pytzタイムゾーンを完全にサポートしており、春/秋のDSTシフトにスムーズに対応できます。

OPによる編集:

Pandasのタイムスタンプとは対照的に、実際のP​​ythonの日時が必要な場合は、

pd.date_range(end = pd.datetime.today(), periods = 100).to_pydatetime().tolist()

元の質問と一致させるために "end"パラメータを使用しますが、降順の日付が必要な場合は、次のようにします。

pd.date_range(pd.datetime.today(), periods=100).to_pydatetime().tolist()
188
fantabolous

指定された開始日と終了日の間の日付範囲を取得します(時空間の複雑さに合わせて最適化)。

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

今日から始まる日付オブジェクトを返すジェネレータ関数を書くことができます。

import datetime

def date_generator():
  from_date = datetime.datetime.today()
  while True:
    yield from_date
    from_date = from_date - datetime.timedelta(days=1)

このジェネレータは、今日から始まって一度に1日後に戻る日付を返します。最初の3つの日付を取る方法は次のとおりです。

>>> 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)]

ループまたはリスト内包表記に対するこのアプローチの利点は、必要なだけ何度でも戻ることができることです。

編集

関数の代わりにジェネレータ式を使ったもっとコンパクトなバージョン:

date_generator = (datetime.datetime.today() - datetime.timedelta(days=i) for i in itertools.count())

使用法:

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

また、日の序数を使って簡単にすることもできます。

def date_range(start_date, end_date):
    for ordinal in range(start_date.toordinal(), end_date.toordinal()):
        yield datetime.date.fromordinal(ordinal)

あるいはコメントで示唆されているように、あなたはこのようなリストを作成することができます:

date_range = [
    datetime.date.fromordinal(ordinal) 
    for ordinal in range(
        start_date.toordinal(),
        end_date.toordinal(),
    )
]
31
Hosane

うん、ホイールを再発明する....ただフォーラムを検索すればあなたはこのような何かを得るでしょう:

from dateutil import rrule
from datetime import datetime

list(rrule.rrule(rrule.DAILY,count=100,dtstart=datetime.now()))
28
BOFH

この質問のタイトルから、私はrange()のようなものを見つけることを期待していました、それは私が2つの日付を指定して、その間にあるすべての日付でリストを作成させるでしょう。そのようにすれば、前もってそれを知らないのであれば、それら二つの日付の間の日数を計算する必要はありません。

したがって、わずかに話題から外れる危険性があるので、このワンライナーは仕事をします。

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))]

すべてのクレジットを この回答

15
snake_charmer

これは、2つの日付startendの間の日付のリストを示すS.Lottの回答を基にして、少し異なる回答です。以下の例では、2017年の始めから今日まで。

start = datetime.datetime(2017,1,1)
end = datetime.datetime.today()
daterange = [start + datetime.timedelta(days=x) for x in range(0, (end-start).days)]
8
Derek Powell

ちょっと遅い答えですが、私は同じ問題を抱えていて、Pythonの内部範囲関数はこの点では少し欠けていると判断したので、私の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))
7
Rob Young

これが私自身のコードから作成した要旨です。 (私はその質問が古すぎることを知っていますが、他の人がそれを使うことができます)

https://Gist.github.com/2287345

(以下同じ)

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

平日のリストを取得するためのbashスクリプトのための1つのライナーがあります。これはpython 3です。

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

これは開始日(または終了日)を指定するための変形です。

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

これは任意の開始日と終了日の変形です。これはそれほど効率的ではありませんが、bashスクリプトにforループを入れるのに適しています。

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

2つの日付があり、範囲が必要な場合

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

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

私が自分で書いた答えに基づいて:

import datetime;
print [(datetime.date.today() - datetime.timedelta(days=x)).strftime('%Y-%m-%d') for x in range(-5, 0)]

出力:

['2017-12-11', '2017-12-10', '2017-12-09', '2017-12-08', '2017-12-07']

違いは、 'datetime.datetime'オブジェクトではなく、 'date'オブジェクトを取得することです。

3
wmlynarski

私はこれが答えられたことを知っています、しかし私は歴史的な目的のために私の答えを書き留めます、そして私はそれが簡単であると思うので。

import numpy as np
import datetime as dt
listOfDates=[date for date in np.arange(firstDate,lastDate,dt.timedelta(days=x))]

確かにそれはコードゴルフのようなものに勝つことはありませんが、私はそれがエレガントだと思います。

2
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

datetimedateutilを持つ月ごとの日付範囲ジェネレータ。シンプルでわかりやすい

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