[pukiwiki]
Pythonのrange関数っぽい感じで、日付を扱える互換品(?)を作ってみました。
<<追記>>
日付文字列でなく、time型使ったほうがすっきり書けるかも。
記事最後に追記
[/pukiwiki]
クローラで収集したデータなど、ファイル名が日付になっているものを処理するときなどに。
(最初は、日付ごとにコールバック関数を呼び出すようにしてたのですが、それだと処理がややこしくなったので、range関数っぽく書き直してみました。このほうが使いやすー)
詳しくはソースを読んでいただくとして、、、
パラメータの指定のしかたによって、微妙に挙動が、直感と違う場合がありますのでご注意
(特に、stepに負数や小数点以下を使用した場合や、 開始日よりも終了日のほうが前の場合など)
daterange(開始日付文字列, 終了日付文字列, ステップ) または daterange(開始日付文字列,日数 ,ステップ) キーワード引数 format=日付形式指定文字列 ・%y/%m/%d 09/04/17 ・%Y-%m-%d 2009-04-17 ・%Y/%m/%d %H:%M 2009/04/17 00:00 timeモジュールを使ってるので、時刻も指定できたりします。 step=3/24. で3時間ごとの時刻文字列作成、などなど
動作サンプル
>>> [x for x in daterange("20090417",3)] ['20090417', '20090418', '20090419'] >>> [x for x in daterange("2009/04/17 09:00","2009/04/17 11:30",step=0.5/24.,format="%Y/%m/%d %H:%M")] ['2009/04/17 09:00', '2009/04/17 09:30', '2009/04/17 10:00', '2009/04/17 10:30', '2009/04/17 11:00', '2009/04/17 11:30']
#!/usr/bin/env python # -*- coding: utf8 -*- "daterange.py" import time import types def sgn(x) : return 1 if x>0 else -1 if x<0 else 0 def daterange(date_start,date_end,step=1, format="%Y%m%d",oneday=24*60*60,step_sec=0): u""" ・daterange(開始日付文字列, 終了日付文字列, ステップ) ・daterange(開始日付文字列,日数 ,ステップ) ・キーワード引数 format=日付形式指定文字列 """ if not step and not step_sec: return elif not step_sec : step_sec=step*oneday t0=time.strptime(date_start ,format) s0=time.mktime(t0) t=type(date_end) if t == types.StringType : t1=time.strptime(date_end ,format) s1=time.mktime(t1) if sgn(s1-s0)!=sgn(step_sec): step_sec*=-1. for s in xrange(s0,s1,step_sec): yield time.strftime(format,time.localtime(s)) yield date_end else : if sgn(date_end)!=sgn(step_sec): step_sec*=-1. for s in xrange(0,oneday*date_end,step_sec): yield time.strftime(format,time.localtime(s0+s)) if __name__=="__main__": format="%y-%m-%d" dt1="20090417" dt2="20090423" date1=[x for x in daterange(dt1,dt2)] date2=[x for x in daterange(dt2,dt1)] date3=[x for x in daterange(dt1,7)] date4=[x for x in daterange(dt2,-7,1)] date2.reverse() date4.reverse() assert date1==date2==date3==date4 ,"error\n%s\n%s\n%s\n%s"%(date1,date2,date3,date4) print "OK" for i,dt in enumerate(daterange(dt1,dt2)) : print i,dt
<<追記>>
文字列でなく、timeモジュール使ったほうがスッキリ書けるかも。
import time oneday=24*60*60 def timedelta(t,x): return time.localtime(time.mktime(t)+x) def timerange(time_start,time_end, step=oneday): s0=time.mktime(time_start) s1=time.mktime(time_end) for s in xrange(s0,s1,step): yield time.localtime(s) yield time_end if __name__=="__main__": fmt="%Y/%m/%d" t0=time.strptime("2009/04/18",fmt) for t in timerange(t0,timedelta(t0,(7-1)*oneday),oneday): print time.strftime(fmt,t)
実行例
2009/04/18 2009/04/19 2009/04/20 2009/04/21 2009/04/22 2009/04/23 2009/04/24