Skip to content

Instantly share code, notes, and snippets.

@salexkidd
Last active December 16, 2015 12:19
Show Gist options
  • Save salexkidd/5433727 to your computer and use it in GitHub Desktop.
Save salexkidd/5433727 to your computer and use it in GitHub Desktop.
Pythonでdatetime の range系がないんだけど、こういうのって他にもあるのかしら・・・ とりあえず書いてみたものの、もし同じようなのがあれば捨てるし、なければgithubにあげてversioningする
#!/usr/bin/python
# -*- coding:utf-8 -*-
"""
Time Range Object Class
"""
from datetime import datetime
from time import mktime
class DateTimeRange(object):
"""
DateTime Range Class
"""
def __init__(self, s_dt, e_dt):
"""
s_dt : rangeの始めとなるdatetimeを指定してください
e_dt : rangeの終わりとなるdatetimeを指定してください
"""
#Check argument
if not all([isinstance(d, datetime) for d in (s_dt, e_dt)]):
raise TypeError("Invalid argument(need datetime instance).")
#check value
if s_dt > e_dt:
raise ValueError("start_datetime future than end_datetime")
self._start_datetime = s_dt
self._end_datetime = e_dt
@property
def start_datetime_to_unixtime(self):
"""
指定されたrangeの始めとなる datetime を unixtime に変換して返します
"""
return int(mktime(self._start_datetime.timetuple()))
@property
def end_datetime_to_unixtime(self):
"""
指定されたrangeの終わりとなる datetime を unixtime に変換して返します
"""
return int(mktime(self._end_datetime.timetuple()))
@property
def start_datetime(self):
"""
指定された range の始めとなる datetime を返します
"""
return self._start_datetime
@property
def end_datetime(self):
"""
指定された range の終わりとなる datetime を返します
"""
return self._end_datetime
def __iter__(self):
"""
startからendまでのdatetimeを返します
>>> from pprint import pprint
>>> start_datetime = datetime(2013, 1, 1, 0, 0, 0)
>>> end_datetime = datetime(2013, 1, 1, 0, 0, 3)
>>> dr = DateTimeRange(start_datetime, end_datetime)
>>> pprint([dt for dt in dr])
[datetime.datetime(2013, 1, 1, 0, 0),
datetime.datetime(2013, 1, 1, 0, 0, 1),
datetime.datetime(2013, 1, 1, 0, 0, 2),
datetime.datetime(2013, 1, 1, 0, 0, 3)]
"""
s = self.start_datetime_to_unixtime
e = self.end_datetime_to_unixtime + 1
for i in range(s, e):
yield datetime.fromtimestamp(i)
def __contains__(self, dt):
"""
渡された datetime object が、time_rangeに含まれているかチェックします
>>> start_datetime = datetime(2013, 1, 1, 0, 0, 0)
>>> end_datetime = datetime(2013, 1, 1, 0, 0, 59)
>>> small_out_of_range_datetime = datetime(2012, 12, 31, 12, 59, 59)
>>> big_out_of_range_datetime = datetime(2013, 1, 1, 1, 2, 0)
>>> dr = DateTimeRange(start_datetime, end_datetime)
>>> start_datetime in dr
True
>>> end_datetime in dr
True
>>> small_out_of_range_datetime in dr
False
>>> big_out_of_range_datetime in dr
False
"""
ret_flg = True
if not isinstance(dt, datetime):
raise TypeError("Invalid argument.")
timestamp_data = int(mktime(dt.timetuple()))
if timestamp_data < self.start_datetime_to_unixtime:
ret_flg = False
if timestamp_data > self.end_datetime_to_unixtime:
ret_flg = False
return ret_flg
def __len__(self):
"""
len method
>>> start_datetime = datetime(2013, 1, 1, 0, 0, 0)
>>> end_datetime = datetime(2013, 1, 1, 0, 0, 3)
>>> dr = DateTimeRange(start_datetime, end_datetime)
>>> len(dr)
4
"""
s = self.start_datetime_to_unixtime
e = self.end_datetime_to_unixtime + 1
return e - s
def __eq__(self, dr):
"""
等式演算
>>> start_datetime = datetime(2013, 1, 1, 0, 0, 0)
>>> end_datetime = datetime(2013, 1, 1, 0, 0, 3)
>>> end_datetime_other = datetime(2013, 1, 1, 0, 0, 4)
>>> dr_one = DateTimeRange(start_datetime, end_datetime)
>>> dr_two = DateTimeRange(start_datetime, end_datetime)
>>> dr_other = DateTimeRange(start_datetime, end_datetime_other)
>>> dr_one == dr_two
True
>>> dr_one == dr_other
False
"""
ret_flg = False
if not isinstance(dr, DateTimeRange):
raise TypeError("Invalid argument.")
if self.start_datetime == dr.start_datetime and self.end_datetime == dr.end_datetime:
ret_flg = True
return ret_flg
if __name__ == "__main__":
import doctest
doctest.testmod()
@salexkidd
Copy link
Author

あと誰か英語にしてけれー

@salexkidd
Copy link
Author

eqに対応した。つまり datetime_range_obj_one == datetime_range_obj_two と比較演算できる。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment