Skip to content

Commit

Permalink
Merge pull request #11 from thombashi/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
thombashi committed Mar 10, 2016
2 parents 1faf75f + 00dc940 commit bbd1739
Show file tree
Hide file tree
Showing 5 changed files with 238 additions and 5 deletions.
104 changes: 104 additions & 0 deletions datetimerange/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import datetime

import dateutil.parser
import dateutil.relativedelta as rdelta
import pytz


Expand Down Expand Up @@ -491,6 +492,109 @@ def set_time_range(self, start, end):
self.set_start_datetime(start)
self.set_end_datetime(end)

@staticmethod
def __compare_relativedelta(lhs, rhs):
if lhs.years < rhs.years:
return -1
if lhs.years > rhs.years:
return 1

if lhs.months < rhs.months:
return -1
if lhs.months > rhs.months:
return 1

if lhs.days < rhs.days:
return -1
if lhs.days > rhs.days:
return 1

if lhs.hours < rhs.hours:
return -1
if lhs.hours > rhs.hours:
return 1

if lhs.minutes < rhs.minutes:
return -1
if lhs.minutes > rhs.minutes:
return 1

if lhs.seconds < rhs.seconds:
return -1
if lhs.seconds > rhs.seconds:
return 1

if lhs.microseconds < rhs.microseconds:
return -1
if lhs.microseconds > rhs.microseconds:
return 1

return 0

def __compare_timedelta(self, lhs, seconds):
try:
rhs = datetime.timedelta(seconds=seconds)

if lhs < rhs:
return -1
if lhs > rhs:
return 1

return 0
except TypeError:
return self.__compare_relativedelta(
lhs.normalized(), rdelta.relativedelta(seconds=seconds))

def range(self, step):
"""
Return an iterator object.
:param datetime.timedelta/dateutil.relativedelta.relativedelta step:
Step of iteration.
:Examples:
.. code:: python
import datetime
from datetimerange import DateTimeRange
time_range = DateTimeRange("2015-01-01T00:00:00+0900", "2015-01-04T00:00:00+0900")
for value in time_range.range(datetime.timedelta(days=1)):
print value
.. parsed-literal::
2015-01-01 00:00:00+09:00
2015-01-02 00:00:00+09:00
2015-01-03 00:00:00+09:00
2015-01-04 00:00:00+09:00
"""

if self.__compare_timedelta(step, 0) == 0:
raise ValueError("step must be not zero")

is_inversion = False
try:
self.validate_time_inversion()
except ValueError:
is_inversion = True

if not is_inversion:
if self.__compare_timedelta(step, seconds=0) < 0:
raise ValueError(
"invalid step: expect greater than 0, actual=%s" % (step))
else:
if self.__compare_timedelta(step, seconds=0) > 0:
raise ValueError(
"invalid step: expect less than 0, actual=%s" % (step))

current_datetime = self.start_datetime
while current_datetime <= self.end_datetime:
yield current_datetime
current_datetime = current_datetime + step

def intersection(self, x):
"""
Newly set a time range that overlaps the input and the current time range.
Expand Down
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
python-dateutil
python-dateutil>=2.5.0
pytz
1 change: 1 addition & 0 deletions requirements/test_requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pytest
pytest-cov
python-dateutil>=2.5.0
8 changes: 4 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@

setuptools.setup(
name="DateTimeRange",
version="0.1.3",
version="0.2.0",
author="Tsuyoshi Hombashi",
author_email="gogogo.vm@gmail.com",
url="https://github.com/thombashi/DateTimeRange",
keywords=["datetimerange", "date", "time", "range"],
license="MIT License",
description=summary,
keywords=["date", "time", "range"],
long_description=long_description,
license="MIT License",
include_package_data=True,
packages=setuptools.find_packages(exclude=['test*']),
install_requires=install_requires,
packages=setuptools.find_packages(exclude=['test*']),
setup_requires=["pytest-runner"],
tests_require=tests_require,
classifiers=[
Expand Down
128 changes: 128 additions & 0 deletions test/test_datetimerange.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import datetime

import dateutil
from dateutil.relativedelta import *
from dateutil.parser import *
import pytest

Expand Down Expand Up @@ -519,6 +520,133 @@ def test_normal(self, value, expected):
assert value.is_valid_timerange() == expected


class Test_DateTimeRange_range:

@pytest.mark.parametrize(["value", "step", "expected"], [
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 1, 0)),
datetime.timedelta(seconds=20),
[
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 0, 20),
datetime.datetime(2015, 3, 22, 0, 0, 40),
datetime.datetime(2015, 3, 22, 0, 1, 00),
],
],
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 23, 0, 0, 0)),
relativedelta(hours=+6),
[
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 6, 0, 0),
datetime.datetime(2015, 3, 22, 12, 0, 0),
datetime.datetime(2015, 3, 22, 18, 0, 0),
datetime.datetime(2015, 3, 23, 0, 0, 0),
],
],
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 23, 0, 0, 0)),
relativedelta(months=+6),
[
datetime.datetime(2015, 3, 22, 0, 0, 0),
],
],
[
DateTimeRange(
"2015-01-01T00:00:00+0900",
"2016-01-01T00:00:00+0900"),
relativedelta(months=+4),
[
parse("2015-01-01T00:00:00+0900"),
parse("2015-05-01T00:00:00+0900"),
parse("2015-09-01T00:00:00+0900"),
parse("2016-01-01T00:00:00+0900"),
],
],
[
DateTimeRange(
datetime.datetime(2015, 3, 23, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 0, 0)),
relativedelta(hours=-6),
[
datetime.datetime(2015, 3, 23, 0, 0, 0),
datetime.datetime(2015, 3, 22, 18, 0, 0),
datetime.datetime(2015, 3, 22, 12, 0, 0),
datetime.datetime(2015, 3, 22, 6, 0, 0),
datetime.datetime(2015, 3, 22, 0, 0, 0),
],
],
])
def test_normal(self, value, step, expected):
for value_item, expected_item in zip(value.range(step), expected):
assert value_item == expected_item

@pytest.mark.parametrize(["value", "step", "expected"], [
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 1, 0)),
relativedelta(seconds=-60),
ValueError,
],
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 1, 0),
datetime.datetime(2015, 3, 22, 0, 0, 0)),
relativedelta(seconds=+60),
ValueError,
],
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 1, 0)),
None,
AttributeError,
],
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 1, 0)),
1,
AttributeError,
],
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 1, 0)),
datetime.timedelta(seconds=0),
ValueError,
],
[
DateTimeRange(
datetime.datetime(2015, 3, 22, 0, 0, 0),
datetime.datetime(2015, 3, 22, 0, 1, 0)),
relativedelta(months=+0),
ValueError,
],
[
None,
relativedelta(months=+4),
AttributeError,
],
[
10,
relativedelta(months=+4),
AttributeError,
],
])
def test_exception(self, value, step, expected):
with pytest.raises(expected):
for i in value.range(step):
pass


class Test_DateTimeRange_is_intersection:

@pytest.mark.parametrize(["lhs", "rhs", "expected"], [
Expand Down

0 comments on commit bbd1739

Please sign in to comment.