Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/isoduration/operations/__init__.py: 17%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

36 statements  

1from __future__ import annotations 

2 

3from datetime import datetime 

4from decimal import ROUND_HALF_UP, Decimal 

5from typing import TYPE_CHECKING 

6 

7from isoduration.operations.util import max_day_in_month, mod2, mod3, quot2, quot3 

8 

9if TYPE_CHECKING: # pragma: no cover 

10 from isoduration.types import Duration 

11 

12 

13def add(start: datetime, duration: Duration) -> datetime: 

14 """ 

15 https://www.w3.org/TR/xmlschema-2/#adding-durations-to-dateTimes 

16 """ 

17 

18 # Months. 

19 temp = Decimal(start.month) + duration.date.months 

20 end_month = mod3(temp, Decimal(1), Decimal(13)) 

21 carry = quot3(temp, Decimal(1), Decimal(13)) 

22 

23 # Years. 

24 end_year = Decimal(start.year) + duration.date.years + carry 

25 

26 # Zone. 

27 end_tzinfo = start.tzinfo 

28 

29 # Seconds. 

30 temp = Decimal(start.second) + duration.time.seconds 

31 end_second = mod2(temp, Decimal("60")) 

32 carry = quot2(temp, Decimal("60")) 

33 

34 # Minutes. 

35 temp = Decimal(start.minute) + duration.time.minutes + carry 

36 end_minute = mod2(temp, Decimal("60")) 

37 carry = quot2(temp, Decimal("60")) 

38 

39 # Hours. 

40 temp = Decimal(start.hour) + duration.time.hours + carry 

41 end_hour = mod2(temp, Decimal("24")) 

42 carry = quot2(temp, Decimal("24")) 

43 

44 # Days. 

45 end_max_day_in_month = max_day_in_month(end_year, end_month) 

46 

47 if start.day > end_max_day_in_month: 

48 temp = end_max_day_in_month 

49 else: 

50 temp = Decimal(start.day) 

51 

52 end_day = temp + duration.date.days + (7 * duration.date.weeks) + carry 

53 

54 while True: 

55 if end_day < 1: 

56 end_day += max_day_in_month(end_year, end_month - 1) 

57 carry = Decimal(-1) 

58 elif end_day > max_day_in_month(end_year, end_month): 

59 end_day -= max_day_in_month(end_year, end_month) 

60 carry = Decimal(1) 

61 else: 

62 break 

63 

64 temp = end_month + carry 

65 end_month = mod3(temp, Decimal(1), Decimal(13)) 

66 end_year = end_year + quot3(temp, Decimal(1), Decimal(13)) 

67 

68 return datetime( 

69 year=int(end_year.to_integral_value(ROUND_HALF_UP)), 

70 month=int(end_month.to_integral_value(ROUND_HALF_UP)), 

71 day=int(end_day.to_integral_value(ROUND_HALF_UP)), 

72 hour=int(end_hour.to_integral_value(ROUND_HALF_UP)), 

73 minute=int(end_minute.to_integral_value(ROUND_HALF_UP)), 

74 second=int(end_second.to_integral_value(ROUND_HALF_UP)), 

75 tzinfo=end_tzinfo, 

76 )