Code

Sending of PGP-Encrypted mail to all users or selected users (via roles)
[roundup.git] / test / test_dates.py
1 #
2 # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
3 # This module is free software, and you may redistribute it and/or modify
4 # under the same terms as Python, so long as this copyright message and
5 # disclaimer are retained in their original form.
6 #
7 # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
8 # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
9 # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
10 # POSSIBILITY OF SUCH DAMAGE.
11 #
12 # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17 #
18 # $Id: test_dates.py,v 1.45 2008-03-07 01:11:55 richard Exp $
19 from __future__ import nested_scopes
21 import unittest
22 import time
23 import datetime
24 import calendar
26 from roundup import date, i18n
27 from roundup.date import Date, Interval, Range, fixTimeOverflow, \
28     get_timezone
31 class DateTestCase(unittest.TestCase):
32     def setUp(self):
33         self.old_gettext_ = i18n.gettext
34         self.old_ngettext_ = i18n.ngettext
35         i18n.gettext = i18n.get_translation(language='C').gettext
36         i18n.ngettext = i18n.get_translation(language='C').ngettext
38     def tearDown(self):
39         i18n.gettext = self.old_gettext_
40         i18n.ngettext = self.old_ngettext_
42     def testDateInterval(self):
43         ae = self.assertEqual
44         date = Date("2000-06-26.00:34:02 + 2d")
45         ae(str(date), '2000-06-28.00:34:02')
46         date = Date("2000-02-27 + 2d")
47         ae(str(date), '2000-02-29.00:00:00')
48         date = Date("2001-02-27 + 2d")
49         ae(str(date), '2001-03-01.00:00:00')
50         date = Date("2009", add_granularity=True)
51         self.assertRaises(ValueError, Date, ". +30d", add_granularity=True)
52         
53     def testDate(self):
54         ae = self.assertEqual
55         date = Date("2000-04-17")
56         ae(str(date), '2000-04-17.00:00:00')
57         date = Date("2000/04/17")
58         ae(str(date), '2000-04-17.00:00:00')
59         date = Date("2000-4-7")
60         ae(str(date), '2000-04-07.00:00:00')
61         date = Date("2000-4-17")
62         ae(str(date), '2000-04-17.00:00:00')
63         date = Date("01-25")
64         y, m, d, x, x, x, x, x, x = time.gmtime(time.time())
65         ae(str(date), '%s-01-25.00:00:00'%y)
66         date = Date("2000-04-17.03:45")
67         ae(str(date), '2000-04-17.03:45:00')
68         date = Date("2000/04/17.03:45")
69         ae(str(date), '2000-04-17.03:45:00')
70         date = Date("08-13.22:13")
71         ae(str(date), '%s-08-13.22:13:00'%y)
72         date = Date("11-07.09:32:43")
73         ae(str(date), '%s-11-07.09:32:43'%y)
74         date = Date("14:25")
75         ae(str(date), '%s-%02d-%02d.14:25:00'%(y, m, d))
76         date = Date("8:47:11")
77         ae(str(date), '%s-%02d-%02d.08:47:11'%(y, m, d))
78         ae(str(Date('2003')), '2003-01-01.00:00:00')
79         ae(str(Date('2004-06')), '2004-06-01.00:00:00')
80         ae(str(Date('1900-02-01')), '1900-02-01.00:00:00')
81         ae(str(Date('1800-07-15')), '1800-07-15.00:00:00')
83     def testLeapYear(self):
84         self.assertEquals(str(Date('2008-02-29')), '2008-02-29.00:00:00')
86     def testDateError(self):
87         self.assertRaises(ValueError, Date, "12")
88         # Date cannot handle dates before year 1
89         self.assertRaises(ValueError, Date, (0, 1, 1, 0, 0, 0.0, 0, 1, -1))
90         self.assertRaises(ValueError, Date, "1/1/06")
92     def testOffset(self):
93         ae = self.assertEqual
94         date = Date("2000-04-17", -5)
95         ae(str(date), '2000-04-17.05:00:00')
96         date = Date("01-25", -5)
97         y, m, d, x, x, x, x, x, x = time.gmtime(time.time())
98         ae(str(date), '%s-01-25.05:00:00'%y)
99         date = Date("2000-04-17.03:45", -5)
100         ae(str(date), '2000-04-17.08:45:00')
101         date = Date("08-13.22:13", -5)
102         ae(str(date), '%s-08-14.03:13:00'%y)
103         date = Date("11-07.09:32:43", -5)
104         ae(str(date), '%s-11-07.14:32:43'%y)
105         date = Date("14:25", -5)
106         ae(str(date), '%s-%02d-%02d.19:25:00'%(y, m, d))
107         date = Date("8:47:11", -5)
108         ae(str(date), '%s-%02d-%02d.13:47:11'%(y, m, d))
110         # just make sure we parse these, m'kay?
111         date = Date('-1d')
112         date = Date('-1w')
113         date = Date('-1m')
114         date = Date('-1y')
116     def testOffsetRandom(self):
117         ae = self.assertEqual
118         # XXX unsure of the usefulness of these, they're pretty random
119         date = Date('2000-01-01') + Interval('- 2y 2m')
120         ae(str(date), '1997-11-01.00:00:00')
121         date = Date('2000-01-01 - 2y 2m')
122         ae(str(date), '1997-11-01.00:00:00')
123         date = Date('2000-01-01') + Interval('2m')
124         ae(str(date), '2000-03-01.00:00:00')
125         date = Date('2000-01-01 + 2m')
126         ae(str(date), '2000-03-01.00:00:00')
128         date = Date('2000-01-01') + Interval('60d')
129         ae(str(date), '2000-03-01.00:00:00')
130         date = Date('2001-01-01') + Interval('60d')
131         ae(str(date), '2001-03-02.00:00:00')
133     def testOffsetAdd(self):
134         ae = self.assertEqual
135         date = Date('2000-02-28.23:59:59') + Interval('00:00:01')
136         ae(str(date), '2000-02-29.00:00:00')
137         date = Date('2001-02-28.23:59:59') + Interval('00:00:01')
138         ae(str(date), '2001-03-01.00:00:00')
140         date = Date('2000-02-28.23:58:59') + Interval('00:01:01')
141         ae(str(date), '2000-02-29.00:00:00')
142         date = Date('2001-02-28.23:58:59') + Interval('00:01:01')
143         ae(str(date), '2001-03-01.00:00:00')
145         date = Date('2000-02-28.22:58:59') + Interval('01:01:01')
146         ae(str(date), '2000-02-29.00:00:00')
147         date = Date('2001-02-28.22:58:59') + Interval('01:01:01')
148         ae(str(date), '2001-03-01.00:00:00')
150         date = Date('2000-02-28.22:58:59') + Interval('00:00:3661')
151         ae(str(date), '2000-02-29.00:00:00')
152         date = Date('2001-02-28.22:58:59') + Interval('00:00:3661')
153         ae(str(date), '2001-03-01.00:00:00')
154         date = Date('2001-03-01.00:00:00') + Interval('150y')
155         ae(str(date), '2151-03-01.00:00:00')
157     def testOffsetSub(self):
158         ae = self.assertEqual
159         date = Date('2000-12-01') - Interval('- 1d')
161         date = Date('2000-01-01') - Interval('- 2y 2m')
162         ae(str(date), '2002-03-01.00:00:00')
163         date = Date('2000-01-01') - Interval('2m')
164         ae(str(date), '1999-11-01.00:00:00')
166         date = Date('2000-03-01') - Interval('60d')
167         ae(str(date), '2000-01-01.00:00:00')
168         date = Date('2001-03-02') - Interval('60d')
169         ae(str(date), '2001-01-01.00:00:00')
171         date = Date('2000-02-29.00:00:00') - Interval('00:00:01')
172         ae(str(date), '2000-02-28.23:59:59')
173         date = Date('2001-03-01.00:00:00') - Interval('00:00:01')
174         ae(str(date), '2001-02-28.23:59:59')
176         date = Date('2000-02-29.00:00:00') - Interval('00:01:01')
177         ae(str(date), '2000-02-28.23:58:59')
178         date = Date('2001-03-01.00:00:00') - Interval('00:01:01')
179         ae(str(date), '2001-02-28.23:58:59')
181         date = Date('2000-02-29.00:00:00') - Interval('01:01:01')
182         ae(str(date), '2000-02-28.22:58:59')
183         date = Date('2001-03-01.00:00:00') - Interval('01:01:01')
184         ae(str(date), '2001-02-28.22:58:59')
186         date = Date('2000-02-29.00:00:00') - Interval('00:00:3661')
187         ae(str(date), '2000-02-28.22:58:59')
188         date = Date('2001-03-01.00:00:00') - Interval('00:00:3661')
189         ae(str(date), '2001-02-28.22:58:59')
190         date = Date('2001-03-01.00:00:00') - Interval('150y')
191         ae(str(date), '1851-03-01.00:00:00')
193     def testDateLocal(self):
194         ae = self.assertEqual
195         date = Date("02:42:20")
196         date = date.local(10)
197         y, m, d, x, x, x, x, x, x = time.gmtime(time.time())
198         ae(str(date), '%s-%02d-%02d.12:42:20'%(y, m, d))
200     def testIntervalInit(self):
201         ae = self.assertEqual
202         ae(str(Interval('3y')), '+ 3y')
203         ae(str(Interval('2 y 1 m')), '+ 2y 1m')
204         ae(str(Interval('1m 25d')), '+ 1m 25d')
205         ae(str(Interval('-2w 3 d ')), '- 17d')
206         ae(str(Interval(' - 1 d 2:50 ')), '- 1d 2:50')
207         ae(str(Interval(' 14:00 ')), '+ 14:00')
208         ae(str(Interval(' 0:04:33 ')), '+ 0:04:33')
209         ae(str(Interval(8.*3600)), '+ 8:00')
211     def testIntervalInitDate(self):
212         ae = self.assertEqual
213         now = Date('.')
214         now.hour = now.minute = now.second = 0
215         then = now + Interval('2d')
216         ae((Interval(str(then))), Interval('- 2d'))
217         then = now - Interval('2d')
218         ae(Interval(str(then)), Interval('+ 2d'))
220     def testIntervalAddMonthBoundary(self):
221         # force the transition over a month boundary
222         now = Date('2003-10-30.00:00:00')
223         then = now + Interval('2d')
224         self.assertEqual(str(then), '2003-11-01.00:00:00')
225         now = Date('2004-02-28.00:00:00')
226         then = now + Interval('1d')
227         self.assertEqual(str(then), '2004-02-29.00:00:00')
228         now = Date('2003-02-28.00:00:00')
229         then = now + Interval('1d')
230         self.assertEqual(str(then), '2003-03-01.00:00:00')
231         now = Date('2003-01-01.00:00:00')
232         then = now + Interval('59d')
233         self.assertEqual(str(then), '2003-03-01.00:00:00')
234         now = Date('2004-01-01.00:00:00')
235         then = now + Interval('59d')
236         self.assertEqual(str(then), '2004-02-29.00:00:00')
238     def testIntervalSubtractMonthBoundary(self):
239         # force the transition over a month boundary
240         now = Date('2003-11-01.00:00:00')
241         then = now - Interval('2d')
242         self.assertEqual(str(then), '2003-10-30.00:00:00')
243         now = Date('2004-02-29.00:00:00')
244         then = now - Interval('1d')
245         self.assertEqual(str(then), '2004-02-28.00:00:00')
246         now = Date('2003-03-01.00:00:00')
247         then = now - Interval('1d')
248         self.assertEqual(str(then), '2003-02-28.00:00:00')
249         now = Date('2003-03-01.00:00:00')
250         then = now - Interval('59d')
251         self.assertEqual(str(then), '2003-01-01.00:00:00')
252         now = Date('2004-02-29.00:00:00')
253         then = now - Interval('59d')
254         self.assertEqual(str(then), '2004-01-01.00:00:00')
256     def testIntervalAddYearBoundary(self):
257         # force the transition over a year boundary
258         now = Date('2003-12-30.00:00:00')
259         then = now + Interval('2d')
260         self.assertEqual(str(then), '2004-01-01.00:00:00')
261         now = Date('2003-01-01.00:00:00')
262         then = now + Interval('365d')
263         self.assertEqual(str(then), '2004-01-01.00:00:00')
264         now = Date('2004-01-01.00:00:00')
265         then = now + Interval('366d')
266         self.assertEqual(str(then), '2005-01-01.00:00:00')
268     def testIntervalSubtractYearBoundary(self):
269         # force the transition over a year boundary
270         now = Date('2003-01-01.00:00:00')
271         then = now - Interval('2d')
272         self.assertEqual(str(then), '2002-12-30.00:00:00')
273         now = Date('2004-02-01.00:00:00')
274         then = now - Interval('365d')
275         self.assertEqual(str(then), '2003-02-01.00:00:00')
276         now = Date('2005-02-01.00:00:00')
277         then = now - Interval('365d')
278         self.assertEqual(str(then), '2004-02-02.00:00:00')
280     def testDateSubtract(self):
281         # These are thoroughly broken right now.
282         i = Date('2003-03-15.00:00:00') - Date('2003-03-10.00:00:00')
283         self.assertEqual(i, Interval('5d'))
284         i = Date('2003-02-01.00:00:00') - Date('2003-03-01.00:00:00')
285         self.assertEqual(i, Interval('-28d'))
286         i = Date('2003-03-01.00:00:00') - Date('2003-02-01.00:00:00')
287         self.assertEqual(i, Interval('28d'))
288         i = Date('2003-03-03.00:00:00') - Date('2003-02-01.00:00:00')
289         self.assertEqual(i, Interval('30d'))
290         i = Date('2003-03-03.00:00:00') - Date('2002-02-01.00:00:00')
291         self.assertEqual(i, Interval('395d'))
292         i = Date('2003-03-03.00:00:00') - Date('2003-04-01.00:00:00')
293         self.assertEqual(i, Interval('-29d'))
294         i = Date('2003-03-01.00:00:00') - Date('2003-02-01.00:00:00')
295         self.assertEqual(i, Interval('28d'))
296         # force the transition over a year boundary
297         i = Date('2003-01-01.00:00:00') - Date('2002-01-01.00:00:00')
298         self.assertEqual(i, Interval('365d'))
299         i = Date('1952-01-01') - Date('1953-01-01')
300         self.assertEqual(i, Interval('-366d'))
301         i = Date('1953-01-01') - Date('1952-01-01')
302         self.assertEqual(i, Interval('366d'))
304     def testIntervalAdd(self):
305         ae = self.assertEqual
306         ae(str(Interval('1y') + Interval('1y')), '+ 2y')
307         ae(str(Interval('1y') + Interval('1m')), '+ 1y 1m')
308         ae(str(Interval('1y') + Interval('2:40')), '+ 1y 2:40')
309         ae(str(Interval('1y') + Interval('- 1y')), '00:00')
310         ae(str(Interval('- 1y') + Interval('1y')), '00:00')
311         ae(str(Interval('- 1y') + Interval('- 1y')), '- 2y')
312         ae(str(Interval('1y') + Interval('- 1m')), '+ 11m')
313         ae(str(Interval('1:00') + Interval('1:00')), '+ 2:00')
314         ae(str(Interval('0:50') + Interval('0:50')), '+ 1:40')
315         ae(str(Interval('1:50') + Interval('- 1:50')), '00:00')
316         ae(str(Interval('- 1:50') + Interval('1:50')), '00:00')
317         ae(str(Interval('- 1:50') + Interval('- 1:50')), '- 3:40')
318         ae(str(Interval('1:59:59') + Interval('00:00:01')), '+ 2:00')
319         ae(str(Interval('2:00') + Interval('- 00:00:01')), '+ 1:59:59')
321     def testIntervalSub(self):
322         ae = self.assertEqual
323         ae(str(Interval('1y') - Interval('- 1y')), '+ 2y')
324         ae(str(Interval('1y') - Interval('- 1m')), '+ 1y 1m')
325         ae(str(Interval('1y') - Interval('- 2:40')), '+ 1y 2:40')
326         ae(str(Interval('1y') - Interval('1y')), '00:00')
327         ae(str(Interval('1y') - Interval('1m')), '+ 11m')
328         ae(str(Interval('1:00') - Interval('- 1:00')), '+ 2:00')
329         ae(str(Interval('0:50') - Interval('- 0:50')), '+ 1:40')
330         ae(str(Interval('1:50') - Interval('1:50')), '00:00')
331         ae(str(Interval('1:59:59') - Interval('- 00:00:01')), '+ 2:00')
332         ae(str(Interval('2:00') - Interval('00:00:01')), '+ 1:59:59')
334     def testOverflow(self):
335         ae = self.assertEqual
336         ae(fixTimeOverflow((1,0,0,0, 0, 0, 60)), (1,0,0,0, 0, 1, 0))
337         ae(fixTimeOverflow((1,0,0,0, 0, 0, 100)), (1,0,0,0, 0, 1, 40))
338         ae(fixTimeOverflow((1,0,0,0, 0, 0, 60*60)), (1,0,0,0, 1, 0, 0))
339         ae(fixTimeOverflow((1,0,0,0, 0, 0, 24*60*60)), (1,0,0,1, 0, 0, 0))
340         ae(fixTimeOverflow((1,0,0,0, 0, 0, -1)), (-1,0,0,0, 0, 0, 1))
341         ae(fixTimeOverflow((1,0,0,0, 0, 0, -100)), (-1,0,0,0, 0, 1, 40))
342         ae(fixTimeOverflow((1,0,0,0, 0, 0, -60*60)), (-1,0,0,0, 1, 0, 0))
343         ae(fixTimeOverflow((1,0,0,0, 0, 0, -24*60*60)), (-1,0,0,1, 0, 0, 0))
344         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 1)), (-1,0,0,0, 0, 0, 1))
345         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 100)), (-1,0,0,0, 0, 1, 40))
346         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 60*60)), (-1,0,0,0, 1, 0, 0))
347         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 24*60*60)), (-1,0,0,1, 0, 0, 0))
349     def testDivision(self):
350         ae = self.assertEqual
351         ae(str(Interval('1y')/2), '+ 6m')
352         ae(str(Interval('1:00')/2), '+ 0:30')
353         ae(str(Interval('00:01')/2), '+ 0:00:30')
355     def testSorting(self):
356         ae = self.assertEqual
357         i1 = Interval('1y')
358         i2 = Interval('1d')
359         l = [i1, i2]; l.sort()
360         ae(l, [i2, i1])
361         l = [i2, i1]; l.sort()
362         ae(l, [i2, i1])
363         i1 = Interval('- 2d')
364         i2 = Interval('1d')
365         l = [i1, i2]; l.sort()
366         ae(l, [i1, i2])
368         i1 = Interval("1:20")
369         i2 = Interval("2d")
370         i3 = Interval("3:30")
371         l = [i1, i2, i3]; l.sort()
372         ae(l, [i1, i3, i2])
374     def testGranularity(self):
375         ae = self.assertEqual
376         ae(str(Date('2003-2-12', add_granularity=1)), '2003-02-12.23:59:59')
377         ae(str(Date('2003-1-1.23:00', add_granularity=1)), '2003-01-01.23:00:59')
378         ae(str(Date('2003', add_granularity=1)), '2003-12-31.23:59:59')
379         ae(str(Date('2003-5', add_granularity=1)), '2003-05-31.23:59:59')
380         ae(str(Date('2003-12', add_granularity=1)), '2003-12-31.23:59:59')
381         ae(str(Interval('+1w', add_granularity=1)), '+ 14d')
382         ae(str(Interval('-2m 3w', add_granularity=1)), '- 2m 14d')
384     def testIntervalPretty(self):
385         def ae(spec, pretty):
386             self.assertEqual(Interval(spec).pretty(), pretty)
387         ae('2y', 'in 2 years')
388         ae('1y', 'in 1 year')
389         ae('2m', 'in 2 months')
390         ae('1m 30d', 'in 2 months')
391         ae('60d', 'in 2 months')
392         ae('59d', 'in 1 month')
393         ae('1m', 'in 1 month')
394         ae('29d', 'in 1 month')
395         ae('28d', 'in 4 weeks')
396         ae('8d', 'in 1 week')
397         ae('7d', 'in 7 days')
398         ae('1w', 'in 7 days')
399         ae('2d', 'in 2 days')
400         ae('1d', 'tomorrow')
401         ae('02:00:00', 'in 2 hours')
402         ae('01:59:00', 'in 1 3/4 hours')
403         ae('01:45:00', 'in 1 3/4 hours')
404         ae('01:30:00', 'in 1 1/2 hours')
405         ae('01:29:00', 'in 1 1/4 hours')
406         ae('01:00:00', 'in an hour')
407         ae('00:30:00', 'in 1/2 an hour')
408         ae('00:15:00', 'in 1/4 hour')
409         ae('00:02:00', 'in 2 minutes')
410         ae('00:01:00', 'in 1 minute')
411         ae('00:00:30', 'in a moment')
412         ae('-00:00:30', 'just now')
413         ae('-1d', 'yesterday')
414         ae('-1y', '1 year ago')
415         ae('-2y', '2 years ago')
417     def testPyDatetime(self):
418         d = datetime.datetime.now()
419         Date(d)
420         toomuch = datetime.MAXYEAR + 1
421         self.assertRaises(ValueError, Date, (toomuch, 1, 1, 0, 0, 0, 0, 1, -1))
423     def testSimpleTZ(self):
424         ae = self.assertEqual
425         # local to utc
426         date = Date('2006-04-04.12:00:00', 2)
427         ae(str(date), '2006-04-04.10:00:00')
428         # utc to local
429         date = Date('2006-04-04.10:00:00')
430         date = date.local(2)
431         ae(str(date), '2006-04-04.12:00:00')
432         # from Date instance
433         date = Date('2006-04-04.12:00:00')
434         date = Date(date, 2)
435         ae(str(date), '2006-04-04.10:00:00')
437     def testTimestamp(self):
438         ae = self.assertEqual
439         date = Date('2038')
440         ae(date.timestamp(), 2145916800)
441         date = Date('1902')
442         ae(date.timestamp(), -2145916800)
443         date = Date(time.gmtime(0))
444         ae(date.timestamp(), 0)
445         ae(str(date), '1970-01-01.00:00:00')
446         date = Date(time.gmtime(0x7FFFFFFF))
447         ae(date.timestamp(), 2147483647)
448         ae(str(date), '2038-01-19.03:14:07')
449         date = Date('1901-12-13.20:45:52')
450         ae(date.timestamp(), -0x80000000L)
451         ae(str(date), '1901-12-13.20:45:52')
452         date = Date('9999')
453         ae (date.timestamp(), 253370764800.0)
454         date = Date('0033')
455         ae (date.timestamp(), -61125753600.0)
456         ae(str(date), '0033-01-01.00:00:00')
458 class TimezoneTestCase(unittest.TestCase):
460     def testTZ(self):
461         ae = self.assertEqual
462         tz = 'Europe/Warsaw'
464         # local to utc, DST
465         date = Date('2006-04-04.12:00:00', tz)
466         ae(str(date), '2006-04-04.10:00:00')
468         # local to utc, no DST
469         date = Date('2006-01-01.12:00:00', tz)
470         ae(str(date), '2006-01-01.11:00:00')
472         # utc to local, DST
473         date = Date('2006-04-04.10:00:00')
474         date = date.local(tz)
475         ae(str(date), '2006-04-04.12:00:00')
477         # utc to local, no DST
478         date = Date('2006-01-01.10:00:00')
479         date = date.local(tz)
480         ae(str(date), '2006-01-01.11:00:00')
482         date = Date('2006-04-04.12:00:00')
483         date = Date(date, tz)
484         ae(str(date), '2006-04-04.10:00:00')
485         date = Date('2006-01-01.12:00:00')
486         date = Date(date, tz)
487         ae(str(date), '2006-01-01.11:00:00')
490 class RangeTestCase(unittest.TestCase):
492     def testRange(self):
493         ae = self.assertEqual
494         r = Range('2006', Date)
495         ae(str(r.from_value), '2006-01-01.00:00:00')
496         ae(str(r.to_value), '2006-12-31.23:59:59')
497         for i in range(1, 13):
498             r = Range('2006-%02d'%i, Date)
499             ae(str(r.from_value), '2006-%02d-01.00:00:00'%i)
500             ae(str(r.to_value), '2006-%02d-%02d.23:59:59'%(i,
501                 calendar.mdays[i]))
504 def test_suite():
505     suite = unittest.TestSuite()
506     suite.addTest(unittest.makeSuite(DateTestCase))
507     suite.addTest(unittest.makeSuite(RangeTestCase))
508     try:
509         import pytz
510     except ImportError:
511         pass
512     else:
513         suite.addTest(unittest.makeSuite(TimezoneTestCase))
514     return suite
516 if __name__ == '__main__':
517     runner = unittest.TextTestRunner()
518     unittest.main(testRunner=runner)
520 # vim: set filetype=python sts=4 sw=4 et si :