Code

*** empty log message ***
[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.31 2003-12-04 23:06:53 richard Exp $
19 from __future__ import nested_scopes
21 import unittest, time
23 from roundup.date import Date, Interval, Range, fixTimeOverflow
25 class DateTestCase(unittest.TestCase):
26     def testDateInterval(self):
27         ae = self.assertEqual
28         date = Date("2000-06-26.00:34:02 + 2d")
29         ae(str(date), '2000-06-28.00:34:02')
30         date = Date("2000-02-27 + 2d")
31         ae(str(date), '2000-02-29.00:00:00')
32         date = Date("2001-02-27 + 2d")
33         ae(str(date), '2001-03-01.00:00:00')
35     def testDate(self):
36         ae = self.assertEqual
37         date = Date("2000-04-17")
38         ae(str(date), '2000-04-17.00:00:00')
39         date = Date("2000/04/17")
40         ae(str(date), '2000-04-17.00:00:00')
41         date = Date("2000-4-7")
42         ae(str(date), '2000-04-07.00:00:00')
43         date = Date("2000-4-17")
44         ae(str(date), '2000-04-17.00:00:00')
45         date = Date("01-25")
46         y, m, d, x, x, x, x, x, x = time.gmtime(time.time())
47         ae(str(date), '%s-01-25.00:00:00'%y)
48         date = Date("2000-04-17.03:45")
49         ae(str(date), '2000-04-17.03:45:00')
50         date = Date("2000/04/17.03:45")
51         ae(str(date), '2000-04-17.03:45:00')
52         date = Date("08-13.22:13")
53         ae(str(date), '%s-08-13.22:13:00'%y)
54         date = Date("11-07.09:32:43")
55         ae(str(date), '%s-11-07.09:32:43'%y)
56         date = Date("14:25")
57         ae(str(date), '%s-%02d-%02d.14:25:00'%(y, m, d))
58         date = Date("8:47:11")
59         ae(str(date), '%s-%02d-%02d.08:47:11'%(y, m, d))
60         ae(str(Date('2003')), '2003-01-01.00:00:00')
61         ae(str(Date('2004-06')), '2004-06-01.00:00:00')
63     def testDateError(self):
64         self.assertRaises(ValueError, Date, "12")
66     def testOffset(self):
67         ae = self.assertEqual
68         date = Date("2000-04-17", -5)
69         ae(str(date), '2000-04-17.05:00:00')
70         date = Date("01-25", -5)
71         y, m, d, x, x, x, x, x, x = time.gmtime(time.time())
72         ae(str(date), '%s-01-25.05:00:00'%y)
73         date = Date("2000-04-17.03:45", -5)
74         ae(str(date), '2000-04-17.08:45:00')
75         date = Date("08-13.22:13", -5)
76         ae(str(date), '%s-08-14.03:13:00'%y)
77         date = Date("11-07.09:32:43", -5)
78         ae(str(date), '%s-11-07.14:32:43'%y)
79         date = Date("14:25", -5)
80         ae(str(date), '%s-%02d-%02d.19:25:00'%(y, m, d))
81         date = Date("8:47:11", -5)
82         ae(str(date), '%s-%02d-%02d.13:47:11'%(y, m, d))
84     def testOffsetRandom(self):
85         ae = self.assertEqual
86         # XXX unsure of the usefulness of these, they're pretty random
87         date = Date('2000-01-01') + Interval('- 2y 2m')
88         ae(str(date), '1997-11-01.00:00:00')
89         date = Date('2000-01-01 - 2y 2m')
90         ae(str(date), '1997-11-01.00:00:00')
91         date = Date('2000-01-01') + Interval('2m')
92         ae(str(date), '2000-03-01.00:00:00')
93         date = Date('2000-01-01 + 2m')
94         ae(str(date), '2000-03-01.00:00:00')
96         date = Date('2000-01-01') + Interval('60d')
97         ae(str(date), '2000-03-01.00:00:00')
98         date = Date('2001-01-01') + Interval('60d')
99         ae(str(date), '2001-03-02.00:00:00')
101     def testOffsetAdd(self):
102         ae = self.assertEqual
103         date = Date('2000-02-28.23:59:59') + Interval('00:00:01')
104         ae(str(date), '2000-02-29.00:00:00')
105         date = Date('2001-02-28.23:59:59') + Interval('00:00:01')
106         ae(str(date), '2001-03-01.00:00:00')
108         date = Date('2000-02-28.23:58:59') + Interval('00:01:01')
109         ae(str(date), '2000-02-29.00:00:00')
110         date = Date('2001-02-28.23:58:59') + Interval('00:01:01')
111         ae(str(date), '2001-03-01.00:00:00')
113         date = Date('2000-02-28.22:58:59') + Interval('01:01:01')
114         ae(str(date), '2000-02-29.00:00:00')
115         date = Date('2001-02-28.22:58:59') + Interval('01:01:01')
116         ae(str(date), '2001-03-01.00:00:00')
118         date = Date('2000-02-28.22:58:59') + Interval('00:00:3661')
119         ae(str(date), '2000-02-29.00:00:00')
120         date = Date('2001-02-28.22:58:59') + Interval('00:00:3661')
121         ae(str(date), '2001-03-01.00:00:00')
123     def testOffsetSub(self):
124         ae = self.assertEqual
125         date = Date('2000-12-01') - Interval('- 1d')
127         date = Date('2000-01-01') - Interval('- 2y 2m')
128         ae(str(date), '2002-03-01.00:00:00')
129         date = Date('2000-01-01') - Interval('2m')
130         ae(str(date), '1999-11-01.00:00:00')
132         date = Date('2000-03-01') - Interval('60d')
133         ae(str(date), '2000-01-01.00:00:00')
134         date = Date('2001-03-02') - Interval('60d')
135         ae(str(date), '2001-01-01.00:00:00')
137         date = Date('2000-02-29.00:00:00') - Interval('00:00:01')
138         ae(str(date), '2000-02-28.23:59:59')
139         date = Date('2001-03-01.00:00:00') - Interval('00:00:01')
140         ae(str(date), '2001-02-28.23:59:59')
142         date = Date('2000-02-29.00:00:00') - Interval('00:01:01')
143         ae(str(date), '2000-02-28.23:58:59')
144         date = Date('2001-03-01.00:00:00') - Interval('00:01:01')
145         ae(str(date), '2001-02-28.23:58:59')
147         date = Date('2000-02-29.00:00:00') - Interval('01:01:01')
148         ae(str(date), '2000-02-28.22:58:59')
149         date = Date('2001-03-01.00:00:00') - Interval('01:01:01')
150         ae(str(date), '2001-02-28.22:58:59')
152         date = Date('2000-02-29.00:00:00') - Interval('00:00:3661')
153         ae(str(date), '2000-02-28.22:58:59')
154         date = Date('2001-03-01.00:00:00') - Interval('00:00:3661')
155         ae(str(date), '2001-02-28.22:58:59')
157     def testDateLocal(self):
158         ae = self.assertEqual
159         date = Date("02:42:20")
160         date = date.local(10)
161         y, m, d, x, x, x, x, x, x = time.gmtime(time.time())
162         ae(str(date), '%s-%02d-%02d.12:42:20'%(y, m, d))
164     def testIntervalInit(self):
165         ae = self.assertEqual
166         ae(str(Interval('3y')), '+ 3y')
167         ae(str(Interval('2 y 1 m')), '+ 2y 1m')
168         ae(str(Interval('1m 25d')), '+ 1m 25d')
169         ae(str(Interval('-2w 3 d ')), '- 17d')
170         ae(str(Interval(' - 1 d 2:50 ')), '- 1d 2:50')
171         ae(str(Interval(' 14:00 ')), '+ 14:00')
172         ae(str(Interval(' 0:04:33 ')), '+ 0:04:33')
174     def testIntervalInitDate(self):
175         ae = self.assertEqual
176         now = Date('.')
177         now.hour = now.minute = now.second = 0
178         then = now + Interval('2d')
179         ae((Interval(str(then))), Interval('- 2d'))
180         then = now - Interval('2d')
181         ae(Interval(str(then)), Interval('+ 2d'))
183     def testIntervalAddMonthBoundary(self):
184         # force the transition over a month boundary
185         now = Date('2003-10-30.00:00:00')
186         then = now + Interval('2d')
187         self.assertEqual(str(then), '2003-11-01.00:00:00')
188         now = Date('2004-02-28.00:00:00')
189         then = now + Interval('1d')
190         self.assertEqual(str(then), '2004-02-29.00:00:00')
191         now = Date('2003-02-28.00:00:00')
192         then = now + Interval('1d')
193         self.assertEqual(str(then), '2003-03-01.00:00:00')
194         now = Date('2003-01-01.00:00:00')
195         then = now + Interval('59d')
196         self.assertEqual(str(then), '2003-03-01.00:00:00')
197         now = Date('2004-01-01.00:00:00')
198         then = now + Interval('59d')
199         self.assertEqual(str(then), '2004-02-29.00:00:00')
201     def testIntervalSubtractMonthBoundary(self):
202         # force the transition over a month boundary
203         now = Date('2003-11-01.00:00:00')
204         then = now - Interval('2d')
205         self.assertEqual(str(then), '2003-10-30.00:00:00')
206         now = Date('2004-02-29.00:00:00')
207         then = now - Interval('1d')
208         self.assertEqual(str(then), '2004-02-28.00:00:00')
209         now = Date('2003-03-01.00:00:00')
210         then = now - Interval('1d')
211         self.assertEqual(str(then), '2003-02-28.00:00:00')
212         now = Date('2003-03-01.00:00:00')
213         then = now - Interval('59d')
214         self.assertEqual(str(then), '2003-01-01.00:00:00')
215         now = Date('2004-02-29.00:00:00')
216         then = now - Interval('59d')
217         self.assertEqual(str(then), '2004-01-01.00:00:00')
219     def testIntervalAddYearBoundary(self):
220         # force the transition over a year boundary
221         now = Date('2003-12-30.00:00:00')
222         then = now + Interval('2d')
223         self.assertEqual(str(then), '2004-01-01.00:00:00')
224         now = Date('2003-01-01.00:00:00')
225         then = now + Interval('365d')
226         self.assertEqual(str(then), '2004-01-01.00:00:00')
227         now = Date('2004-01-01.00:00:00')
228         then = now + Interval('366d')
229         self.assertEqual(str(then), '2005-01-01.00:00:00')
231     def testIntervalSubtractYearBoundary(self):
232         # force the transition over a year boundary
233         now = Date('2003-01-01.00:00:00')
234         then = now - Interval('2d')
235         self.assertEqual(str(then), '2002-12-30.00:00:00')
236         now = Date('2004-02-01.00:00:00')
237         then = now - Interval('365d')
238         self.assertEqual(str(then), '2003-02-01.00:00:00')
239         now = Date('2005-02-01.00:00:00')
240         then = now - Interval('365d')
241         self.assertEqual(str(then), '2004-02-02.00:00:00')
243     def testDateSubtract(self):
244         # These are thoroughly broken right now.
245         i = Date('2003-03-15.00:00:00') - Date('2003-03-10.00:00:00')
246         self.assertEqual(i, Interval('5d'))
247         i = Date('2003-02-01.00:00:00') - Date('2003-03-01.00:00:00')
248         self.assertEqual(i, Interval('-28d'))
249         i = Date('2003-03-01.00:00:00') - Date('2003-02-01.00:00:00')
250         self.assertEqual(i, Interval('28d'))
251         i = Date('2003-03-03.00:00:00') - Date('2003-02-01.00:00:00')
252         self.assertEqual(i, Interval('30d'))
253         i = Date('2003-03-03.00:00:00') - Date('2002-02-01.00:00:00')
254         self.assertEqual(i, Interval('395d'))
255         i = Date('2003-03-03.00:00:00') - Date('2003-04-01.00:00:00')
256         self.assertEqual(i, Interval('-29d'))
257         i = Date('2003-03-01.00:00:00') - Date('2003-02-01.00:00:00')
258         self.assertEqual(i, Interval('28d'))
259         # force the transition over a year boundary
260         i = Date('2003-01-01.00:00:00') - Date('2002-01-01.00:00:00')
261         self.assertEqual(i, Interval('365d'))
263     def testIntervalAdd(self):
264         ae = self.assertEqual
265         ae(str(Interval('1y') + Interval('1y')), '+ 2y')
266         ae(str(Interval('1y') + Interval('1m')), '+ 1y 1m')
267         ae(str(Interval('1y') + Interval('2:40')), '+ 1y 2:40')
268         ae(str(Interval('1y') + Interval('- 1y')), '')
269         ae(str(Interval('- 1y') + Interval('1y')), '')
270         ae(str(Interval('- 1y') + Interval('- 1y')), '- 2y')
271         ae(str(Interval('1y') + Interval('- 1m')), '+ 11m')
272         ae(str(Interval('1:00') + Interval('1:00')), '+ 2:00')
273         ae(str(Interval('0:50') + Interval('0:50')), '+ 1:40')
274         ae(str(Interval('1:50') + Interval('- 1:50')), '')
275         ae(str(Interval('- 1:50') + Interval('1:50')), '')
276         ae(str(Interval('- 1:50') + Interval('- 1:50')), '- 3:40')
277         ae(str(Interval('1:59:59') + Interval('00:00:01')), '+ 2:00')
278         ae(str(Interval('2:00') + Interval('- 00:00:01')), '+ 1:59:59')
280     def testIntervalSub(self):
281         ae = self.assertEqual
282         ae(str(Interval('1y') - Interval('- 1y')), '+ 2y')
283         ae(str(Interval('1y') - Interval('- 1m')), '+ 1y 1m')
284         ae(str(Interval('1y') - Interval('- 2:40')), '+ 1y 2:40')
285         ae(str(Interval('1y') - Interval('1y')), '')
286         ae(str(Interval('1y') - Interval('1m')), '+ 11m')
287         ae(str(Interval('1:00') - Interval('- 1:00')), '+ 2:00')
288         ae(str(Interval('0:50') - Interval('- 0:50')), '+ 1:40')
289         ae(str(Interval('1:50') - Interval('1:50')), '')
290         ae(str(Interval('1:59:59') - Interval('- 00:00:01')), '+ 2:00')
291         ae(str(Interval('2:00') - Interval('00:00:01')), '+ 1:59:59')
293     def testOverflow(self):
294         ae = self.assertEqual
295         ae(fixTimeOverflow((1,0,0,0, 0, 0, 60)), (1,0,0,0, 0, 1, 0))
296         ae(fixTimeOverflow((1,0,0,0, 0, 0, 100)), (1,0,0,0, 0, 1, 40))
297         ae(fixTimeOverflow((1,0,0,0, 0, 0, 60*60)), (1,0,0,0, 1, 0, 0))
298         ae(fixTimeOverflow((1,0,0,0, 0, 0, 24*60*60)), (1,0,0,1, 0, 0, 0))
299         ae(fixTimeOverflow((1,0,0,0, 0, 0, -1)), (-1,0,0,0, 0, 0, 1))
300         ae(fixTimeOverflow((1,0,0,0, 0, 0, -100)), (-1,0,0,0, 0, 1, 40))
301         ae(fixTimeOverflow((1,0,0,0, 0, 0, -60*60)), (-1,0,0,0, 1, 0, 0))
302         ae(fixTimeOverflow((1,0,0,0, 0, 0, -24*60*60)), (-1,0,0,1, 0, 0, 0))
303         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 1)), (-1,0,0,0, 0, 0, 1))
304         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 100)), (-1,0,0,0, 0, 1, 40))
305         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 60*60)), (-1,0,0,0, 1, 0, 0))
306         ae(fixTimeOverflow((-1,0,0,0, 0, 0, 24*60*60)), (-1,0,0,1, 0, 0, 0))
308     def testDivision(self):
309         ae = self.assertEqual
310         ae(str(Interval('1y')/2), '+ 6m')
311         ae(str(Interval('1:00')/2), '+ 0:30')
312         ae(str(Interval('00:01')/2), '+ 0:00:30')
314     def testSorting(self):
315         ae = self.assertEqual
316         i1 = Interval('1y')
317         i2 = Interval('1d')
318         l = [i1, i2]; l.sort()
319         ae(l, [i2, i1])
320         l = [i2, i1]; l.sort()
321         ae(l, [i2, i1])
322         i1 = Interval('- 2d')
323         i2 = Interval('1d')
324         l = [i1, i2]; l.sort()
325         ae(l, [i1, i2])
327         i1 = Interval("1:20")
328         i2 = Interval("2d")
329         i3 = Interval("3:30")
330         l = [i1, i2, i3]; l.sort()
331         ae(l, [i1, i3, i2])
333     def testGranularity(self):
334         ae = self.assertEqual
335         ae(str(Date('2003-2-12', add_granularity=1)), '2003-02-12.23:59:59')
336         ae(str(Date('2003-1-1.23:00', add_granularity=1)), '2003-01-01.23:00:59')
337         ae(str(Date('2003', add_granularity=1)), '2003-12-31.23:59:59')
338         ae(str(Date('2003-5', add_granularity=1)), '2003-05-31.23:59:59')
339         ae(str(Interval('+1w', add_granularity=1)), '+ 14d')
340         ae(str(Interval('-2m 3w', add_granularity=1)), '- 2m 14d')
341         
342     def testIntervalPretty(self):
343         def ae(spec, pretty):
344             self.assertEqual(Interval(spec).pretty(), pretty)
345         ae('2y', 'in 2 years')
346         ae('1y', 'in 1 year')
347         ae('2m', 'in 2 months')
348         ae('1m 30d', 'in 2 months')
349         ae('60d', 'in 2 months')
350         ae('59d', 'in 1 month')
351         ae('1m', 'in 1 month')
352         ae('29d', 'in 1 month')
353         ae('28d', 'in 4 weeks')
354         ae('8d', 'in 1 week')
355         ae('7d', 'in 7 days')
356         ae('1w', 'in 7 days')
357         ae('2d', 'in 2 days')
358         ae('1d', 'tomorrow')
359         ae('02:00:00', 'in 2 hours')
360         ae('01:59:00', 'in 1 3/4 hours')
361         ae('01:45:00', 'in 1 3/4 hours')
362         ae('01:30:00', 'in 1 1/2 hours')
363         ae('01:29:00', 'in 1 1/4 hours')
364         ae('01:00:00', 'in an hour')        
365         ae('00:30:00', 'in 1/2 an hour')
366         ae('00:15:00', 'in 1/4 hour')
367         ae('00:02:00', 'in 2 minutes')
368         ae('00:01:00', 'in 1 minute')
369         ae('00:00:30', 'in a moment')
370         ae('-00:00:30', 'just now')
371         ae('-1d', 'yesterday')
372         ae('-1y', '1 year ago')
373         ae('-2y', '2 years ago')
375 def test_suite():
376     suite = unittest.TestSuite()
377     suite.addTest(unittest.makeSuite(DateTestCase))
378     return suite
380 if __name__ == '__main__':
381     runner = unittest.TextTestRunner()
382     unittest.main(testRunner=runner)
384 # vim: set filetype=python ts=4 sw=4 et si