今日から始めて、任意の日数、たとえば私の例では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
やや優れている...
base = datetime.datetime.today()
date_list = [base - datetime.timedelta(days=x) for x in range(0, numdays)]
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のタイムスタンプとは対照的に、実際のPythonの日時が必要な場合は、
pd.date_range(end = pd.datetime.today(), periods = 100).to_pydatetime().tolist()
元の質問と一致させるために "end"パラメータを使用しますが、降順の日付が必要な場合は、次のようにします。
pd.date_range(pd.datetime.today(), periods=100).to_pydatetime().tolist()
指定された開始日と終了日の間の日付範囲を取得します(時空間の複雑さに合わせて最適化)。
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")
今日から始まる日付オブジェクトを返すジェネレータ関数を書くことができます。
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)]
また、日の序数を使って簡単にすることもできます。
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(),
)
]
うん、ホイールを再発明する....ただフォーラムを検索すればあなたはこのような何かを得るでしょう:
from dateutil import rrule
from datetime import datetime
list(rrule.rrule(rrule.DAILY,count=100,dtstart=datetime.now()))
この質問のタイトルから、私は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))]
すべてのクレジットを この回答 !
これは、2つの日付start
とend
の間の日付のリストを示す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)]
ちょっと遅い答えですが、私は同じ問題を抱えていて、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))
これが私自身のコードから作成した要旨です。 (私はその質問が古すぎることを知っていますが、他の人がそれを使うことができます)
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
平日のリストを取得するための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
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)))
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)
私が自分で書いた答えに基づいて:
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
'オブジェクトを取得することです。
私はこれが答えられたことを知っています、しかし私は歴史的な目的のために私の答えを書き留めます、そして私はそれが簡単であると思うので。
import numpy as np
import datetime as dt
listOfDates=[date for date in np.arange(firstDate,lastDate,dt.timedelta(days=x))]
確かにそれはコードゴルフのようなものに勝つことはありませんが、私はそれがエレガントだと思います。
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
datetime
とdateutil
を持つ月ごとの日付範囲ジェネレータ。シンプルでわかりやすい
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()