summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Fayolle <alexandre.fayolle@logilab.fr>2008-05-07 16:00:39 +0200
committerAlexandre Fayolle <alexandre.fayolle@logilab.fr>2008-05-07 16:00:39 +0200
commit19d9c63eed8e5dfaeaf9c632bddae1b84175af74 (patch)
tree04bc0ce76f81215eff1b1c5afac386793ecd1ad7
parente72c98245b0b9e56ceef170bd9059417c6d6bbc0 (diff)
parent07cabe1c88b27ce385bcacb25ddcd50239b59da8 (diff)
downloadlogilab-common-19d9c63eed8e5dfaeaf9c632bddae1b84175af74.tar.gz
merge
-rw-r--r--date.py30
-rw-r--r--test/unittest_date.py103
-rw-r--r--testlib.py4
3 files changed, 96 insertions, 41 deletions
diff --git a/date.py b/date.py
index 375e220..d49b17d 100644
--- a/date.py
+++ b/date.py
@@ -19,7 +19,7 @@
import math
try:
- from mx.DateTime import RelativeDateTime, strptime
+ from mx.DateTime import RelativeDateTime, strptime, Date
STEP = 1
except ImportError:
from warnings import warn
@@ -65,11 +65,15 @@ else:
def get_national_holidays(begin, end):
"""return french national days off between begin and end"""
+ begin = Date(begin.year, begin.month, begin.day)
+ end = Date(end.year, end.month, end.day)
holidays = [strptime(datestr, '%Y-%m-%d')
for datestr in FRENCH_MOBILE_HOLIDAYS.values()]
for year in xrange(begin.year, end.year+1):
- holidays += [strptime(datestr % year, '%Y-%m-%d')
- for datestr in FRENCH_FIXED_HOLIDAYS.values()]
+ for datestr in FRENCH_FIXED_HOLIDAYS.values():
+ date = strptime(datestr % year, '%Y-%m-%d')
+ if date not in holidays:
+ holidays.append(date)
return [day for day in holidays if begin <= day < end]
@@ -77,10 +81,12 @@ else:
"""adds date but try to only take days worked into account"""
weeks, plus = divmod(days, 5)
end = start+(weeks * 7) + plus
- if end.day_of_week > 4:
- end += 2
+ if end.day_of_week >= 5: # saturday or sunday
+ end += 2
end += len([x for x in get_national_holidays(start, end+1)
if x.day_of_week < 5])
+ if end.day_of_week >= 5: # saturday or sunday
+ end += 2
return end
def nb_open_days(start, end):
@@ -92,19 +98,11 @@ else:
elif end.day_of_week == 6:
plus -= 1
open_days = weeks * 5 + plus
- nb_week_holidays = len([x for x in get_national_holidays(start,
- end+1)
- if x.day_of_week < 5])
+ nb_week_holidays = len([x for x in get_national_holidays(start, end+1)
+ if x.day_of_week < 5 and x < end])
return open_days - nb_week_holidays
- #def nb_open_days(start, end):
- # """ brute-force version """
- # days = [x for x in date_range(start, end) if x.day_of_week < 5]
- # nb_week_holidays = len([x for x in get_national_holidays(start,
- # end+1)
- # if x.day_of_week < 5])
- # return len(days) - nb_week_holidays
-
+
def date_range(begin, end, step=STEP):
"""
enumerate dates between begin and end dates.
diff --git a/test/unittest_date.py b/test/unittest_date.py
index 2a30de6..fc4fa34 100644
--- a/test/unittest_date.py
+++ b/test/unittest_date.py
@@ -7,11 +7,12 @@ from logilab.common.testlib import TestCase, unittest_main
from logilab.common.date import date_range
try:
- from mx.DateTime import Date, RelativeDate, now
- from logilab.common.date import endOfMonth, add_days_worked, nb_open_days
+ from mx.DateTime import Date, RelativeDate, RelativeDateTime, now, DateTime
+ from logilab.common.date import endOfMonth, add_days_worked, nb_open_days, \
+ get_national_holidays
except ImportError:
from datetime import date as Date
- endOfMonth = add_days_worked = nb_open_days = None
+ get_national_holidays = endOfMonth = add_days_worked = nb_open_days = None
class DateTC(TestCase):
@@ -26,8 +27,7 @@ class DateTC(TestCase):
def test_month(self):
"""enumerate months"""
- if endOfMonth is None:
- self.skip('mx.DateTime is not installed')
+ self.check_mx()
r = list(date_range(Date(2000,1,2), Date(2000,4,4), endOfMonth))
expected = [Date(2000,1,2), Date(2000,2,29), Date(2000,3,31)]
self.assertListEquals(r, expected)
@@ -36,8 +36,7 @@ class DateTC(TestCase):
self.assertListEquals(r, expected)
def test_add_days_worked(self):
- if add_days_worked is None:
- self.skip('mx.DateTime is not installed')
+ self.check_mx()
add = add_days_worked
# normal
self.assertEquals(add(Date(2008, 1, 3), 1), Date(2008, 1, 4))
@@ -46,26 +45,82 @@ class DateTC(TestCase):
# skip 2 week-ends
self.assertEquals(add(Date(2008, 1, 3), 8), Date(2008, 1, 15))
# skip holiday + week-end
- self.assertEquals(add(Date(2008, 4, 30), 2), Date(2008, 5, 4))
+ self.assertEquals(add(Date(2008, 4, 30), 2), Date(2008, 5, 5))
- def test_nb_open_days(self):
- if nb_open_days is None:
- self.skip('mx.DateTime is not installed')
+ def test_get_national_holidays(self):
+ self.check_mx()
+ holidays = get_national_holidays
+ yield self.assertEquals, holidays(Date(2008, 4, 29), Date(2008, 5, 2)), \
+ [Date(2008, 5, 1)]
+ yield self.assertEquals, holidays(Date(2008, 5, 7), Date(2008, 5, 8)), []
+ x = DateTime(2008, 5, 7, 12, 12, 12)
+ yield self.assertEquals, holidays(x, x+1), []
+
+ def test_open_days_now_and_before(self):
+ self.check_mx()
nb = nb_open_days
- self.assertEquals(nb(Date(2008, 3, 4), Date(2008, 3, 7)), 3)
- self.assertEquals(nb(Date(2008, 3, 4), Date(2008, 3, 5)), 1)
- self.assertEquals(nb(Date(2008, 3, 7), Date(2008, 3, 10)), 1)
- self.assertEquals(nb(Date(2008, 3, 7), Date(2008, 3, 17)), 6)
- self.assertEquals(nb(Date(2008, 3, 18), Date(2008, 3, 26)), 5)
- self.assertEquals(nb(Date(2008, 3, 7), Date(2008, 3, 8)), 1)
- self.assertEquals(nb(Date(2008, 3, 7), Date(2008, 3, 9)), 1)
- self.assertEquals(nb(Date(2008, 3, 8), Date(2008, 3, 9)), 0)
- self.assertEquals(nb(Date(2008, 3, 8), Date(2008, 3, 10)), 0)
- self.assertEquals(nb(Date(2008, 3, 8), Date(2008, 3, 11)), 1)
x = now()
- self.assertEquals(nb(x,x), 0)
- self.assertEquals(nb(x,x+0.5), 1)
- self.assertRaises(AssertionError, nb, x, x-1)
+ y = x - RelativeDateTime(seconds=1)
+ self.assertRaises(AssertionError, nb, x, y)
+
+ def check_mx(self):
+ if nb_open_days is None:
+ self.skip('mx.DateTime is not installed')
+
+ def assertOpenDays(self, start, stop, expected):
+ self.check_mx()
+ got = nb_open_days(start, stop)
+ self.assertEquals(got, expected)
+
+ def test_open_days_tuesday_friday(self):
+ self.assertOpenDays(Date(2008, 3, 4), Date(2008, 3, 7), 3)
+
+ def test_open_days_day_nextday(self):
+ self.assertOpenDays(Date(2008, 3, 4), Date(2008, 3, 5), 1)
+
+ def test_open_days_friday_monday(self):
+ self.assertOpenDays(Date(2008, 3, 7), Date(2008, 3, 10), 1)
+
+ def test_open_days_friday_monday_with_two_weekends(self):
+ self.assertOpenDays(Date(2008, 3, 7), Date(2008, 3, 17), 6)
+
+ def test_open_days_tuesday_wednesday(self):
+ """week-end + easter monday"""
+ self.assertOpenDays(Date(2008, 3, 18), Date(2008, 3, 26), 5)
+
+ def test_open_days_friday_saturday(self):
+ self.assertOpenDays(Date(2008, 3, 7), Date(2008, 3, 8), 1)
+
+ def test_open_days_friday_sunday(self):
+ self.assertOpenDays(Date(2008, 3, 7), Date(2008, 3, 9), 1)
+
+ def test_open_days_saturday_sunday(self):
+ self.assertOpenDays(Date(2008, 3, 8), Date(2008, 3, 9), 0)
+
+ def test_open_days_saturday_monday(self):
+ self.assertOpenDays(Date(2008, 3, 8), Date(2008, 3, 10), 0)
+
+ def test_open_days_saturday_tuesday(self):
+ self.assertOpenDays(Date(2008, 3, 8), Date(2008, 3, 11), 1)
+
+ def test_open_days_now_now(self):
+ x = now()
+ self.assertOpenDays(x, x, 0)
+
+ def test_open_days_afternoon_before_holiday(self):
+ self.assertOpenDays(DateTime(2008, 5, 7, 14), Date(2008, 5, 8), 1)
+
+ def test_open_days_afternoon_before_saturday(self):
+ self.assertOpenDays(DateTime(2008, 5, 9, 14), Date(2008, 5, 10), 1)
+
+ def test_open_days_afternoon(self):
+ self.assertOpenDays(DateTime(2008, 5, 6, 14), Date(2008, 5, 7), 1)
+
+ def test_open_days_now_and_one_second(self):
+ x = now()
+ y = x + RelativeDateTime(seconds=1)
+ self.assertOpenDays(x, y, 1)
+
if __name__ == '__main__':
unittest_main()
diff --git a/testlib.py b/testlib.py
index 24bab0a..a9acdad 100644
--- a/testlib.py
+++ b/testlib.py
@@ -884,6 +884,7 @@ class TestCase(unittest.TestCase):
self._out = []
self._err = []
self._current_test_descr = None
+ self._options_ = None
def datadir(cls):
"""helper attribute holding the standard test's data directory
@@ -968,6 +969,7 @@ class TestCase(unittest.TestCase):
def _get_test_method(self):
return getattr(self, self.__testMethodName)
+
def optval(self, option, default=None):
return getattr(self._options_, option, default)
@@ -1291,7 +1293,7 @@ class DocTest(TestCase):
without this hack
"""
skipped = ()
- def __call__(self, result=None, runcondition=None):
+ def __call__(self, result=None, runcondition=None, options=None):
try:
finder = DocTestFinder(skipped=self.skipped)
if sys.version_info >= (2, 4):