Coverage for api/utils/dt_utils.py: 35%

61 statements  

« prev     ^ index     » next       coverage.py v7.6.2, created at 2024-10-10 03:02 +0300

1import datetime 

2from contextlib import suppress 

3 

4 

5def get_current_datetime(append_time: int = 0): 

6 time = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc) 

7 if append_time: 

8 time = datetime.datetime.fromtimestamp(time.timestamp() + append_time) 

9 return time 

10 

11 

12def get_datetime_tz_aware(dt: datetime.datetime): 

13 return dt.replace(tzinfo=datetime.timezone.utc) 

14 

15 

16def months_delta( 

17 months: int, dt: datetime.date | datetime.datetime 

18) -> datetime.datetime: 

19 year = dt.year 

20 month = dt.month 

21 day = dt.day 

22 

23 years_delta = (month + months - 1) // 12 

24 resulting_month = (month + months) % 12 

25 if resulting_month == 0: 

26 resulting_month = 12 

27 year += years_delta 

28 

29 # from 31 down to 28 

30 for i in range(4): 

31 with suppress(ValueError): 

32 if isinstance(dt, datetime.datetime): 

33 return datetime.datetime( 

34 year, 

35 resulting_month, 

36 day - i, 

37 dt.hour, 

38 dt.minute, 

39 dt.second, 

40 dt.microsecond, 

41 ) 

42 return datetime.datetime(year, resulting_month, day - i) 

43 raise ValueError 

44 

45 

46def get_deletion_datetime(days_ago: int): 

47 cur_dt = datetime.datetime.utcnow() 

48 return cur_dt - datetime.timedelta(days=days_ago) 

49 

50 

51def parse_datetime_filter(dt_filter: str) -> datetime.datetime: 

52 try: 

53 dt = datetime.datetime.strptime(dt_filter, "%Y-%m-%dT%H:%M:%S") 

54 return dt.astimezone(datetime.timezone.utc) 

55 except ValueError: 

56 return datetime.datetime.strptime(dt_filter, "%Y-%m-%dT%H:%M:%S%z") 

57 

58 

59def parse_datetime_str(dt_in: str, tz: str | None = None): 

60 if tz: 

61 dt_in += tz 

62 return datetime.datetime.strptime(dt_in, "%d.%m.%y %H:%M%z") 

63 return datetime.datetime.strptime(dt_in, "%d.%m.%y %H:%M") 

64 

65 

66def parse_datetime_to_str( 

67 dt_in: datetime.datetime, tz: datetime.tzinfo | None = None 

68) -> str: 

69 format_str = "%d.%m.%y %H:%M" 

70 if tz: 

71 return dt_in.astimezone(tz=tz).strftime(format_str) 

72 return dt_in.strftime(format_str) 

73 

74 

75def ensure_dt( 

76 datetime_column: str | datetime.datetime | None, tz: str | None = None 

77): 

78 if datetime_column is None: 

79 raise ValueError 

80 if isinstance(datetime_column, datetime.datetime): 

81 return datetime_column 

82 return parse_datetime_str(datetime_column, tz) 

83 

84 

85def get_period_num_of_months_back( 

86 n: int, current_date: datetime.datetime 

87) -> tuple[datetime.datetime, datetime.datetime]: 

88 month = (current_date.month - n) % 12 

89 year = current_date.year 

90 if current_date.month - n <= 0: 90 ↛ 91line 90 didn't jump to line 91 because the condition on line 90 was never true

91 year -= 1 

92 if month == 0: 92 ↛ 93line 92 didn't jump to line 93 because the condition on line 92 was never true

93 month = 12 

94 dt = datetime.datetime(year, month, 1) 

95 upper_year = year + 1 if month + 1 > 12 else year 

96 upper_month = month + 1 if month + 1 < 13 else 1 

97 upper_dt = datetime.datetime(upper_year, upper_month, 1) 

98 return dt, upper_dt