dateutil / dateutil
1
# -*- coding: utf-8 -*-
2 20
from __future__ import unicode_literals
3 20
from ._common import NotAValue
4

5 20
import calendar
6 20
from datetime import datetime, date, timedelta
7 20
import unittest
8

9 20
import pytest
10

11 20
from dateutil.relativedelta import relativedelta, MO, TU, WE, FR, SU
12

13

14 20
class RelativeDeltaTest(unittest.TestCase):
15 20
    now = datetime(2003, 9, 17, 20, 54, 47, 282310)
16 20
    today = date(2003, 9, 17)
17

18 20
    def testInheritance(self):
19
        # Ensure that relativedelta is inheritance-friendly.
20 20
        class rdChildClass(relativedelta):
21 20
            pass
22

23 20
        ccRD = rdChildClass(years=1, months=1, days=1, leapdays=1, weeks=1,
24
                            hours=1, minutes=1, seconds=1, microseconds=1)
25

26 20
        rd = relativedelta(years=1, months=1, days=1, leapdays=1, weeks=1,
27
                           hours=1, minutes=1, seconds=1, microseconds=1)
28

29 20
        self.assertEqual(type(ccRD + rd), type(ccRD),
30
                         msg='Addition does not inherit type.')
31

32 20
        self.assertEqual(type(ccRD - rd), type(ccRD),
33
                         msg='Subtraction does not inherit type.')
34

35 20
        self.assertEqual(type(-ccRD), type(ccRD),
36
                         msg='Negation does not inherit type.')
37

38 20
        self.assertEqual(type(ccRD * 5.0), type(ccRD),
39
                         msg='Multiplication does not inherit type.')
40

41 20
        self.assertEqual(type(ccRD / 5.0), type(ccRD),
42
                         msg='Division does not inherit type.')
43

44 20
    def testMonthEndMonthBeginning(self):
45 20
        self.assertEqual(relativedelta(datetime(2003, 1, 31, 23, 59, 59),
46
                                       datetime(2003, 3, 1, 0, 0, 0)),
47
                         relativedelta(months=-1, seconds=-1))
48

49 20
        self.assertEqual(relativedelta(datetime(2003, 3, 1, 0, 0, 0),
50
                                       datetime(2003, 1, 31, 23, 59, 59)),
51
                         relativedelta(months=1, seconds=1))
52

53 20
    def testMonthEndMonthBeginningLeapYear(self):
54 20
        self.assertEqual(relativedelta(datetime(2012, 1, 31, 23, 59, 59),
55
                                       datetime(2012, 3, 1, 0, 0, 0)),
56
                         relativedelta(months=-1, seconds=-1))
57

58 20
        self.assertEqual(relativedelta(datetime(2003, 3, 1, 0, 0, 0),
59
                                       datetime(2003, 1, 31, 23, 59, 59)),
60
                         relativedelta(months=1, seconds=1))
61

62 20
    def testNextMonth(self):
63 20
        self.assertEqual(self.now+relativedelta(months=+1),
64
                         datetime(2003, 10, 17, 20, 54, 47, 282310))
65

66 20
    def testNextMonthPlusOneWeek(self):
67 20
        self.assertEqual(self.now+relativedelta(months=+1, weeks=+1),
68
                         datetime(2003, 10, 24, 20, 54, 47, 282310))
69

70 20
    def testNextMonthPlusOneWeek10am(self):
71 20
        self.assertEqual(self.today +
72
                         relativedelta(months=+1, weeks=+1, hour=10),
73
                         datetime(2003, 10, 24, 10, 0))
74

75 20
    def testNextMonthPlusOneWeek10amDiff(self):
76 20
        self.assertEqual(relativedelta(datetime(2003, 10, 24, 10, 0),
77
                                       self.today),
78
                         relativedelta(months=+1, days=+7, hours=+10))
79

80 20
    def testOneMonthBeforeOneYear(self):
81 20
        self.assertEqual(self.now+relativedelta(years=+1, months=-1),
82
                         datetime(2004, 8, 17, 20, 54, 47, 282310))
83

84 20
    def testMonthsOfDiffNumOfDays(self):
85 20
        self.assertEqual(date(2003, 1, 27)+relativedelta(months=+1),
86
                         date(2003, 2, 27))
87 20
        self.assertEqual(date(2003, 1, 31)+relativedelta(months=+1),
88
                         date(2003, 2, 28))
89 20
        self.assertEqual(date(2003, 1, 31)+relativedelta(months=+2),
90
                         date(2003, 3, 31))
91

92 20
    def testMonthsOfDiffNumOfDaysWithYears(self):
93 20
        self.assertEqual(date(2000, 2, 28)+relativedelta(years=+1),
94
                         date(2001, 2, 28))
95 20
        self.assertEqual(date(2000, 2, 29)+relativedelta(years=+1),
96
                         date(2001, 2, 28))
97

98 20
        self.assertEqual(date(1999, 2, 28)+relativedelta(years=+1),
99
                         date(2000, 2, 28))
100 20
        self.assertEqual(date(1999, 3, 1)+relativedelta(years=+1),
101
                         date(2000, 3, 1))
102 20
        self.assertEqual(date(1999, 3, 1)+relativedelta(years=+1),
103
                         date(2000, 3, 1))
104

105 20
        self.assertEqual(date(2001, 2, 28)+relativedelta(years=-1),
106
                         date(2000, 2, 28))
107 20
        self.assertEqual(date(2001, 3, 1)+relativedelta(years=-1),
108
                         date(2000, 3, 1))
109

110 20
    def testNextFriday(self):
111 20
        self.assertEqual(self.today+relativedelta(weekday=FR),
112
                         date(2003, 9, 19))
113

114 20
    def testNextFridayInt(self):
115 20
        self.assertEqual(self.today+relativedelta(weekday=calendar.FRIDAY),
116
                         date(2003, 9, 19))
117

118 20
    def testLastFridayInThisMonth(self):
119 20
        self.assertEqual(self.today+relativedelta(day=31, weekday=FR(-1)),
120
                         date(2003, 9, 26))
121

122 20
    def testNextWednesdayIsToday(self):
123 20
        self.assertEqual(self.today+relativedelta(weekday=WE),
124
                         date(2003, 9, 17))
125

126 20
    def testNextWenesdayNotToday(self):
127 20
        self.assertEqual(self.today+relativedelta(days=+1, weekday=WE),
128
                         date(2003, 9, 24))
129

130 20
    def testAddMoreThan12Months(self):
131 20
        self.assertEqual(date(2003, 12, 1) + relativedelta(months=+13),
132
                         date(2005, 1, 1))
133

134 20
    def testAddNegativeMonths(self):
135 20
        self.assertEqual(date(2003, 1, 1) + relativedelta(months=-2),
136
                         date(2002, 11, 1))
137

138 20
    def test15thISOYearWeek(self):
139 20
        self.assertEqual(date(2003, 1, 1) +
140
                         relativedelta(day=4, weeks=+14, weekday=MO(-1)),
141
                         date(2003, 4, 7))
142

143 20
    def testMillenniumAge(self):
144 20
        self.assertEqual(relativedelta(self.now, date(2001, 1, 1)),
145
                         relativedelta(years=+2, months=+8, days=+16,
146
                                       hours=+20, minutes=+54, seconds=+47,
147
                                       microseconds=+282310))
148

149 20
    def testJohnAge(self):
150 20
        self.assertEqual(relativedelta(self.now,
151
                                       datetime(1978, 4, 5, 12, 0)),
152
                         relativedelta(years=+25, months=+5, days=+12,
153
                                       hours=+8, minutes=+54, seconds=+47,
154
                                       microseconds=+282310))
155

156 20
    def testJohnAgeWithDate(self):
157 20
        self.assertEqual(relativedelta(self.today,
158
                                       datetime(1978, 4, 5, 12, 0)),
159
                         relativedelta(years=+25, months=+5, days=+11,
160
                                       hours=+12))
161

162 20
    def testYearDay(self):
163 20
        self.assertEqual(date(2003, 1, 1)+relativedelta(yearday=260),
164
                         date(2003, 9, 17))
165 20
        self.assertEqual(date(2002, 1, 1)+relativedelta(yearday=260),
166
                         date(2002, 9, 17))
167 20
        self.assertEqual(date(2000, 1, 1)+relativedelta(yearday=260),
168
                         date(2000, 9, 16))
169 20
        self.assertEqual(self.today+relativedelta(yearday=261),
170
                         date(2003, 9, 18))
171

172 20
    def testYearDayBug(self):
173
        # Tests a problem reported by Adam Ryan.
174 20
        self.assertEqual(date(2010, 1, 1)+relativedelta(yearday=15),
175
                         date(2010, 1, 15))
176

177 20
    def testNonLeapYearDay(self):
178 20
        self.assertEqual(date(2003, 1, 1)+relativedelta(nlyearday=260),
179
                         date(2003, 9, 17))
180 20
        self.assertEqual(date(2002, 1, 1)+relativedelta(nlyearday=260),
181
                         date(2002, 9, 17))
182 20
        self.assertEqual(date(2000, 1, 1)+relativedelta(nlyearday=260),
183
                         date(2000, 9, 17))
184 20
        self.assertEqual(self.today+relativedelta(yearday=261),
185
                         date(2003, 9, 18))
186

187 20
    def testAddition(self):
188 20
        self.assertEqual(relativedelta(days=10) +
189
                         relativedelta(years=1, months=2, days=3, hours=4,
190
                                       minutes=5, microseconds=6),
191
                         relativedelta(years=1, months=2, days=13, hours=4,
192
                                       minutes=5, microseconds=6))
193

194 20
    def testAbsoluteAddition(self):
195 20
        self.assertEqual(relativedelta() + relativedelta(day=0, hour=0),
196
                         relativedelta(day=0, hour=0))
197 20
        self.assertEqual(relativedelta(day=0, hour=0) + relativedelta(),
198
                         relativedelta(day=0, hour=0))
199

200 20
    def testAdditionToDatetime(self):
201 20
        self.assertEqual(datetime(2000, 1, 1) + relativedelta(days=1),
202
                         datetime(2000, 1, 2))
203

204 20
    def testRightAdditionToDatetime(self):
205 20
        self.assertEqual(relativedelta(days=1) + datetime(2000, 1, 1),
206
                         datetime(2000, 1, 2))
207

208 20
    def testAdditionInvalidType(self):
209 20
        with self.assertRaises(TypeError):
210 20
            relativedelta(days=3) + 9
211

212 20
    def testAdditionUnsupportedType(self):
213
        # For unsupported types that define their own comparators, etc.
214 20
        self.assertIs(relativedelta(days=1) + NotAValue, NotAValue)
215

216 20
    def testAdditionFloatValue(self):
217 20
        self.assertEqual(datetime(2000, 1, 1) + relativedelta(days=float(1)),
218
                         datetime(2000, 1, 2))
219 20
        self.assertEqual(datetime(2000, 1, 1) + relativedelta(months=float(1)),
220
                         datetime(2000, 2, 1))
221 20
        self.assertEqual(datetime(2000, 1, 1) + relativedelta(years=float(1)),
222
                         datetime(2001, 1, 1))
223

224 20
    def testAdditionFloatFractionals(self):
225 20
        self.assertEqual(datetime(2000, 1, 1, 0) +
226
                         relativedelta(days=float(0.5)),
227
                         datetime(2000, 1, 1, 12))
228 20
        self.assertEqual(datetime(2000, 1, 1, 0, 0) +
229
                         relativedelta(hours=float(0.5)),
230
                         datetime(2000, 1, 1, 0, 30))
231 20
        self.assertEqual(datetime(2000, 1, 1, 0, 0, 0) +
232
                         relativedelta(minutes=float(0.5)),
233
                         datetime(2000, 1, 1, 0, 0, 30))
234 20
        self.assertEqual(datetime(2000, 1, 1, 0, 0, 0, 0) +
235
                         relativedelta(seconds=float(0.5)),
236
                         datetime(2000, 1, 1, 0, 0, 0, 500000))
237 20
        self.assertEqual(datetime(2000, 1, 1, 0, 0, 0, 0) +
238
                         relativedelta(microseconds=float(500000.25)),
239
                         datetime(2000, 1, 1, 0, 0, 0, 500000))
240

241 20
    def testSubtraction(self):
242 20
        self.assertEqual(relativedelta(days=10) -
243
                         relativedelta(years=1, months=2, days=3, hours=4,
244
                                       minutes=5, microseconds=6),
245
                         relativedelta(years=-1, months=-2, days=7, hours=-4,
246
                                       minutes=-5, microseconds=-6))
247

248 20
    def testRightSubtractionFromDatetime(self):
249 20
        self.assertEqual(datetime(2000, 1, 2) - relativedelta(days=1),
250
                         datetime(2000, 1, 1))
251

252 20
    def testSubractionWithDatetime(self):
253 20
        self.assertRaises(TypeError, lambda x, y: x - y,
254
                          (relativedelta(days=1), datetime(2000, 1, 1)))
255

256 20
    def testSubtractionInvalidType(self):
257 20
        with self.assertRaises(TypeError):
258 20
            relativedelta(hours=12) - 14
259

260 20
    def testSubtractionUnsupportedType(self):
261 20
        self.assertIs(relativedelta(days=1) + NotAValue, NotAValue)
262

263 20
    def testMultiplication(self):
264 20
        self.assertEqual(datetime(2000, 1, 1) + relativedelta(days=1) * 28,
265
                         datetime(2000, 1, 29))
266 20
        self.assertEqual(datetime(2000, 1, 1) + 28 * relativedelta(days=1),
267
                         datetime(2000, 1, 29))
268

269 20
    def testMultiplicationUnsupportedType(self):
270 20
        self.assertIs(relativedelta(days=1) * NotAValue, NotAValue)
271

272 20
    def testDivision(self):
273 20
        self.assertEqual(datetime(2000, 1, 1) + relativedelta(days=28) / 28,
274
                         datetime(2000, 1, 2))
275

276 20
    def testDivisionUnsupportedType(self):
277 20
        self.assertIs(relativedelta(days=1) / NotAValue, NotAValue)
278

279 20
    def testBoolean(self):
280 20
        self.assertFalse(relativedelta(days=0))
281 20
        self.assertTrue(relativedelta(days=1))
282

283 20
    def testAbsoluteValueNegative(self):
284 20
        rd_base = relativedelta(years=-1, months=-5, days=-2, hours=-3,
285
                                minutes=-5, seconds=-2, microseconds=-12)
286 20
        rd_expected = relativedelta(years=1, months=5, days=2, hours=3,
287
                                    minutes=5, seconds=2, microseconds=12)
288 20
        self.assertEqual(abs(rd_base), rd_expected)
289

290 20
    def testAbsoluteValuePositive(self):
291 20
        rd_base = relativedelta(years=1, months=5, days=2, hours=3,
292
                                minutes=5, seconds=2, microseconds=12)
293 20
        rd_expected = rd_base
294

295 20
        self.assertEqual(abs(rd_base), rd_expected)
296

297 20
    def testComparison(self):
298 20
        d1 = relativedelta(years=1, months=1, days=1, leapdays=0, hours=1,
299
                           minutes=1, seconds=1, microseconds=1)
300 20
        d2 = relativedelta(years=1, months=1, days=1, leapdays=0, hours=1,
301
                           minutes=1, seconds=1, microseconds=1)
302 20
        d3 = relativedelta(years=1, months=1, days=1, leapdays=0, hours=1,
303
                           minutes=1, seconds=1, microseconds=2)
304

305 20
        self.assertEqual(d1, d2)
306 20
        self.assertNotEqual(d1, d3)
307

308 20
    def testInequalityTypeMismatch(self):
309
        # Different type
310 20
        self.assertFalse(relativedelta(year=1) == 19)
311

312 20
    def testInequalityUnsupportedType(self):
313 20
        self.assertIs(relativedelta(hours=3) == NotAValue, NotAValue)
314

315 20
    def testInequalityWeekdays(self):
316
        # Different weekdays
317 20
        no_wday = relativedelta(year=1997, month=4)
318 20
        wday_mo_1 = relativedelta(year=1997, month=4, weekday=MO(+1))
319 20
        wday_mo_2 = relativedelta(year=1997, month=4, weekday=MO(+2))
320 20
        wday_tu = relativedelta(year=1997, month=4, weekday=TU)
321

322 20
        self.assertTrue(wday_mo_1 == wday_mo_1)
323

324 20
        self.assertFalse(no_wday == wday_mo_1)
325 20
        self.assertFalse(wday_mo_1 == no_wday)
326

327 20
        self.assertFalse(wday_mo_1 == wday_mo_2)
328 20
        self.assertFalse(wday_mo_2 == wday_mo_1)
329

330 20
        self.assertFalse(wday_mo_1 == wday_tu)
331 20
        self.assertFalse(wday_tu == wday_mo_1)
332

333 20
    def testMonthOverflow(self):
334 20
        self.assertEqual(relativedelta(months=273),
335
                         relativedelta(years=22, months=9))
336

337 20
    def testWeeks(self):
338
        # Test that the weeks property is working properly.
339 20
        rd = relativedelta(years=4, months=2, weeks=8, days=6)
340 20
        self.assertEqual((rd.weeks, rd.days), (8, 8 * 7 + 6))
341

342 20
        rd.weeks = 3
343 20
        self.assertEqual((rd.weeks, rd.days), (3, 3 * 7 + 6))
344

345 20
    def testRelativeDeltaRepr(self):
346 20
        self.assertEqual(repr(relativedelta(years=1, months=-1, days=15)),
347
                         'relativedelta(years=+1, months=-1, days=+15)')
348

349 20
        self.assertEqual(repr(relativedelta(months=14, seconds=-25)),
350
                         'relativedelta(years=+1, months=+2, seconds=-25)')
351

352 20
        self.assertEqual(repr(relativedelta(month=3, hour=3, weekday=SU(3))),
353
                         'relativedelta(month=3, weekday=SU(+3), hour=3)')
354

355 20
    def testRelativeDeltaFractionalYear(self):
356 20
        with self.assertRaises(ValueError):
357 20
            relativedelta(years=1.5)
358

359 20
    def testRelativeDeltaFractionalMonth(self):
360 20
        with self.assertRaises(ValueError):
361 20
            relativedelta(months=1.5)
362

363 20
    def testRelativeDeltaInvalidDatetimeObject(self):
364 20
        with self.assertRaises(TypeError):
365 20
            relativedelta(dt1='2018-01-01', dt2='2018-01-02')
366

367 20
        with self.assertRaises(TypeError):
368 20
            relativedelta(dt1=datetime(2018, 1, 1), dt2='2018-01-02')
369

370 20
        with self.assertRaises(TypeError):
371 20
            relativedelta(dt1='2018-01-01', dt2=datetime(2018, 1, 2))
372

373 20
    def testRelativeDeltaFractionalAbsolutes(self):
374
        # Fractional absolute values will soon be unsupported,
375
        # check for the deprecation warning.
376 20
        with pytest.warns(DeprecationWarning):
377 20
            relativedelta(year=2.86)
378

379 20
        with pytest.warns(DeprecationWarning):
380 20
            relativedelta(month=1.29)
381

382 20
        with pytest.warns(DeprecationWarning):
383 20
            relativedelta(day=0.44)
384

385 20
        with pytest.warns(DeprecationWarning):
386 20
            relativedelta(hour=23.98)
387

388 20
        with pytest.warns(DeprecationWarning):
389 20
            relativedelta(minute=45.21)
390

391 20
        with pytest.warns(DeprecationWarning):
392 20
            relativedelta(second=13.2)
393

394 20
        with pytest.warns(DeprecationWarning):
395 20
            relativedelta(microsecond=157221.93)
396

397 20
    def testRelativeDeltaFractionalRepr(self):
398 20
        rd = relativedelta(years=3, months=-2, days=1.25)
399

400 20
        self.assertEqual(repr(rd),
401
                         'relativedelta(years=+3, months=-2, days=+1.25)')
402

403 20
        rd = relativedelta(hours=0.5, seconds=9.22)
404 20
        self.assertEqual(repr(rd),
405
                         'relativedelta(hours=+0.5, seconds=+9.22)')
406

407 20
    def testRelativeDeltaFractionalWeeks(self):
408
        # Equivalent to days=8, hours=18
409 20
        rd = relativedelta(weeks=1.25)
410 20
        d1 = datetime(2009, 9, 3, 0, 0)
411 20
        self.assertEqual(d1 + rd,
412
                         datetime(2009, 9, 11, 18))
413

414 20
    def testRelativeDeltaFractionalDays(self):
415 20
        rd1 = relativedelta(days=1.48)
416

417 20
        d1 = datetime(2009, 9, 3, 0, 0)
418 20
        self.assertEqual(d1 + rd1,
419
                         datetime(2009, 9, 4, 11, 31, 12))
420

421 20
        rd2 = relativedelta(days=1.5)
422 20
        self.assertEqual(d1 + rd2,
423
                         datetime(2009, 9, 4, 12, 0, 0))
424

425 20
    def testRelativeDeltaFractionalHours(self):
426 20
        rd = relativedelta(days=1, hours=12.5)
427 20
        d1 = datetime(2009, 9, 3, 0, 0)
428 20
        self.assertEqual(d1 + rd,
429
                         datetime(2009, 9, 4, 12, 30, 0))
430

431 20
    def testRelativeDeltaFractionalMinutes(self):
432 20
        rd = relativedelta(hours=1, minutes=30.5)
433 20
        d1 = datetime(2009, 9, 3, 0, 0)
434 20
        self.assertEqual(d1 + rd,
435
                         datetime(2009, 9, 3, 1, 30, 30))
436

437 20
    def testRelativeDeltaFractionalSeconds(self):
438 20
        rd = relativedelta(hours=5, minutes=30, seconds=30.5)
439 20
        d1 = datetime(2009, 9, 3, 0, 0)
440 20
        self.assertEqual(d1 + rd,
441
                         datetime(2009, 9, 3, 5, 30, 30, 500000))
442

443 20
    def testRelativeDeltaFractionalPositiveOverflow(self):
444
        # Equivalent to (days=1, hours=14)
445 20
        rd1 = relativedelta(days=1.5, hours=2)
446 20
        d1 = datetime(2009, 9, 3, 0, 0)
447 20
        self.assertEqual(d1 + rd1,
448
                         datetime(2009, 9, 4, 14, 0, 0))
449

450
        # Equivalent to (days=1, hours=14, minutes=45)
451 20
        rd2 = relativedelta(days=1.5, hours=2.5, minutes=15)
452 20
        d1 = datetime(2009, 9, 3, 0, 0)
453 20
        self.assertEqual(d1 + rd2,
454
                         datetime(2009, 9, 4, 14, 45))
455

456
        # Carry back up - equivalent to (days=2, hours=2, minutes=0, seconds=1)
457 20
        rd3 = relativedelta(days=1.5, hours=13, minutes=59.5, seconds=31)
458 20
        self.assertEqual(d1 + rd3,
459
                         datetime(2009, 9, 5, 2, 0, 1))
460

461 20
    def testRelativeDeltaFractionalNegativeDays(self):
462
        # Equivalent to (days=-1, hours=-1)
463 20
        rd1 = relativedelta(days=-1.5, hours=11)
464 20
        d1 = datetime(2009, 9, 3, 12, 0)
465 20
        self.assertEqual(d1 + rd1,
466
                         datetime(2009, 9, 2, 11, 0, 0))
467

468
        # Equivalent to (days=-1, hours=-9)
469 20
        rd2 = relativedelta(days=-1.25, hours=-3)
470 20
        self.assertEqual(d1 + rd2,
471
            datetime(2009, 9, 2, 3))
472

473 20
    def testRelativeDeltaNormalizeFractionalDays(self):
474
        # Equivalent to (days=2, hours=18)
475 20
        rd1 = relativedelta(days=2.75)
476

477 20
        self.assertEqual(rd1.normalized(), relativedelta(days=2, hours=18))
478

479
        # Equivalent to (days=1, hours=11, minutes=31, seconds=12)
480 20
        rd2 = relativedelta(days=1.48)
481

482 20
        self.assertEqual(rd2.normalized(),
483
            relativedelta(days=1, hours=11, minutes=31, seconds=12))
484

485 20
    def testRelativeDeltaNormalizeFractionalDays2(self):
486
        # Equivalent to (hours=1, minutes=30)
487 20
        rd1 = relativedelta(hours=1.5)
488

489 20
        self.assertEqual(rd1.normalized(), relativedelta(hours=1, minutes=30))
490

491
        # Equivalent to (hours=3, minutes=17, seconds=5, microseconds=100)
492 20
        rd2 = relativedelta(hours=3.28472225)
493

494 20
        self.assertEqual(rd2.normalized(),
495
            relativedelta(hours=3, minutes=17, seconds=5, microseconds=100))
496

497 20
    def testRelativeDeltaNormalizeFractionalMinutes(self):
498
        # Equivalent to (minutes=15, seconds=36)
499 20
        rd1 = relativedelta(minutes=15.6)
500

501 20
        self.assertEqual(rd1.normalized(),
502
            relativedelta(minutes=15, seconds=36))
503

504
        # Equivalent to (minutes=25, seconds=20, microseconds=25000)
505 20
        rd2 = relativedelta(minutes=25.33375)
506

507 20
        self.assertEqual(rd2.normalized(),
508
            relativedelta(minutes=25, seconds=20, microseconds=25000))
509

510 20
    def testRelativeDeltaNormalizeFractionalSeconds(self):
511
        # Equivalent to (seconds=45, microseconds=25000)
512 20
        rd1 = relativedelta(seconds=45.025)
513 20
        self.assertEqual(rd1.normalized(),
514
            relativedelta(seconds=45, microseconds=25000))
515

516 20
    def testRelativeDeltaFractionalPositiveOverflow2(self):
517
        # Equivalent to (days=1, hours=14)
518 20
        rd1 = relativedelta(days=1.5, hours=2)
519 20
        self.assertEqual(rd1.normalized(),
520
            relativedelta(days=1, hours=14))
521

522
        # Equivalent to (days=1, hours=14, minutes=45)
523 20
        rd2 = relativedelta(days=1.5, hours=2.5, minutes=15)
524 20
        self.assertEqual(rd2.normalized(),
525
            relativedelta(days=1, hours=14, minutes=45))
526

527
        # Carry back up - equivalent to:
528
        # (days=2, hours=2, minutes=0, seconds=2, microseconds=3)
529 20
        rd3 = relativedelta(days=1.5, hours=13, minutes=59.50045,
530
                            seconds=31.473, microseconds=500003)
531 20
        self.assertEqual(rd3.normalized(),
532
            relativedelta(days=2, hours=2, minutes=0,
533
                          seconds=2, microseconds=3))
534

535 20
    def testRelativeDeltaFractionalNegativeOverflow(self):
536
        # Equivalent to (days=-1)
537 20
        rd1 = relativedelta(days=-0.5, hours=-12)
538 20
        self.assertEqual(rd1.normalized(),
539
            relativedelta(days=-1))
540

541
        # Equivalent to (days=-1)
542 20
        rd2 = relativedelta(days=-1.5, hours=12)
543 20
        self.assertEqual(rd2.normalized(),
544
            relativedelta(days=-1))
545

546
        # Equivalent to (days=-1, hours=-14, minutes=-45)
547 20
        rd3 = relativedelta(days=-1.5, hours=-2.5, minutes=-15)
548 20
        self.assertEqual(rd3.normalized(),
549
            relativedelta(days=-1, hours=-14, minutes=-45))
550

551
        # Equivalent to (days=-1, hours=-14, minutes=+15)
552 20
        rd4 = relativedelta(days=-1.5, hours=-2.5, minutes=45)
553 20
        self.assertEqual(rd4.normalized(),
554
            relativedelta(days=-1, hours=-14, minutes=+15))
555

556
        # Carry back up - equivalent to:
557
        # (days=-2, hours=-2, minutes=0, seconds=-2, microseconds=-3)
558 20
        rd3 = relativedelta(days=-1.5, hours=-13, minutes=-59.50045,
559
                            seconds=-31.473, microseconds=-500003)
560 20
        self.assertEqual(rd3.normalized(),
561
            relativedelta(days=-2, hours=-2, minutes=0,
562
                          seconds=-2, microseconds=-3))
563

564 20
    def testInvalidYearDay(self):
565 20
        with self.assertRaises(ValueError):
566 20
            relativedelta(yearday=367)
567

568 20
    def testAddTimedeltaToUnpopulatedRelativedelta(self):
569 20
        td = timedelta(
570
            days=1,
571
            seconds=1,
572
            microseconds=1,
573
            milliseconds=1,
574
            minutes=1,
575
            hours=1,
576
            weeks=1
577
        )
578

579 20
        expected = relativedelta(
580
            weeks=1,
581
            days=1,
582
            hours=1,
583
            minutes=1,
584
            seconds=1,
585
            microseconds=1001
586
        )
587

588 20
        self.assertEqual(expected, relativedelta() + td)
589

590 20
    def testAddTimedeltaToPopulatedRelativeDelta(self):
591 20
        td = timedelta(
592
            days=1,
593
            seconds=1,
594
            microseconds=1,
595
            milliseconds=1,
596
            minutes=1,
597
            hours=1,
598
            weeks=1
599
        )
600

601 20
        rd = relativedelta(
602
            year=1,
603
            month=1,
604
            day=1,
605
            hour=1,
606
            minute=1,
607
            second=1,
608
            microsecond=1,
609
            years=1,
610
            months=1,
611
            days=1,
612
            weeks=1,
613
            hours=1,
614
            minutes=1,
615
            seconds=1,
616
            microseconds=1
617
        )
618

619 20
        expected = relativedelta(
620
            year=1,
621
            month=1,
622
            day=1,
623
            hour=1,
624
            minute=1,
625
            second=1,
626
            microsecond=1,
627
            years=1,
628
            months=1,
629
            weeks=2,
630
            days=2,
631
            hours=2,
632
            minutes=2,
633
            seconds=2,
634
            microseconds=1002,
635
        )
636

637 20
        self.assertEqual(expected, rd + td)
638

639 20
    def testHashable(self):
640 20
        try:
641 20
            {relativedelta(minute=1): 'test'}
642 0
        except:
643 0
            self.fail("relativedelta() failed to hash!")
644

645

646 20
class RelativeDeltaWeeksPropertyGetterTest(unittest.TestCase):
647
    """Test the weeks property getter"""
648

649 20
    def test_one_day(self):
650 20
        rd = relativedelta(days=1)
651 20
        self.assertEqual(rd.days, 1)
652 20
        self.assertEqual(rd.weeks, 0)
653

654 20
    def test_minus_one_day(self):
655 20
        rd = relativedelta(days=-1)
656 20
        self.assertEqual(rd.days, -1)
657 20
        self.assertEqual(rd.weeks, 0)
658

659 20
    def test_height_days(self):
660 20
        rd = relativedelta(days=8)
661 20
        self.assertEqual(rd.days, 8)
662 20
        self.assertEqual(rd.weeks, 1)
663

664 20
    def test_minus_height_days(self):
665 20
        rd = relativedelta(days=-8)
666 20
        self.assertEqual(rd.days, -8)
667 20
        self.assertEqual(rd.weeks, -1)
668

669

670 20
class RelativeDeltaWeeksPropertySetterTest(unittest.TestCase):
671
    """Test the weeks setter which makes a "smart" update of the days attribute"""
672

673 20
    def test_one_day_set_one_week(self):
674 20
        rd = relativedelta(days=1)
675 20
        rd.weeks = 1  # add 7 days
676 20
        self.assertEqual(rd.days, 8)
677 20
        self.assertEqual(rd.weeks, 1)
678

679 20
    def test_minus_one_day_set_one_week(self):
680 20
        rd = relativedelta(days=-1)
681 20
        rd.weeks = 1  # add 7 days
682 20
        self.assertEqual(rd.days, 6)
683 20
        self.assertEqual(rd.weeks, 0)
684

685 20
    def test_height_days_set_minus_one_week(self):
686 20
        rd = relativedelta(days=8)
687 20
        rd.weeks = -1  # change from 1 week, 1 day to -1 week, 1 day
688 20
        self.assertEqual(rd.days, -6)
689 20
        self.assertEqual(rd.weeks, 0)
690

691 20
    def test_minus_height_days_set_minus_one_week(self):
692 20
        rd = relativedelta(days=-8)
693 20
        rd.weeks = -1  # does not change anything
694 20
        self.assertEqual(rd.days, -8)
695 20
        self.assertEqual(rd.weeks, -1)
696

697

698
# vim:ts=4:sw=4:et

Read our documentation on viewing source code .

Loading