Last active
December 16, 2015 12:19
-
-
Save salexkidd/5433727 to your computer and use it in GitHub Desktop.
Pythonでdatetime の range系がないんだけど、こういうのって他にもあるのかしら・・・
とりあえず書いてみたものの、もし同じようなのがあれば捨てるし、なければgithubにあげてversioningする
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
eqに対応した。つまり datetime_range_obj_one == datetime_range_obj_two と比較演算できる。