Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/acme2certifier/acme_srv/helpers/datetime_utils.py: 29%

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

49 statements  

1# -*- coding: utf-8 -*- 

2"""Date and time utilities for acme2certifier""" 

3 

4import calendar 

5import datetime 

6import re 

7from typing import Union 

8 

9from dateutil.parser import parse 

10 

11_DURATION_RE = re.compile(r"^(\d+)\s*([smhdw]?)$", re.IGNORECASE) 

12_DURATION_UNIT_SECONDS = { 

13 "": 1, 

14 "s": 1, 

15 "m": 60, 

16 "h": 3600, 

17 "d": 86400, 

18 "w": 604800, 

19} 

20 

21 

22def duration_to_seconds(value: Union[str, int]) -> int: 

23 """Parse a duration into seconds. 

24 

25 Accepts plain integers (seconds) or strings with an optional unit suffix: 

26 ``s`` (seconds), ``m`` (minutes), ``h`` (hours), ``d`` (days), ``w`` (weeks). 

27 Examples: ``172800``, ``"2d"``, ``"48h"``, ``"30m"``. 

28 """ 

29 if isinstance(value, bool): 

30 raise ValueError(f"invalid duration: {value!r}") 

31 if isinstance(value, int): 

32 if value <= 0: 

33 raise ValueError("duration must be positive") 

34 return value 

35 

36 text = str(value).strip() 

37 if not text: 

38 raise ValueError("empty duration") 

39 

40 match = _DURATION_RE.match(text) 

41 if not match: 

42 raise ValueError(f"invalid duration: {value!r}") 

43 

44 amount = int(match.group(1)) 

45 unit = match.group(2).lower() 

46 seconds = amount * _DURATION_UNIT_SECONDS[unit] 

47 if seconds <= 0: 

48 raise ValueError("duration must be positive") 

49 return seconds 

50 

51 

52def uts_now(): 

53 """unixtimestamp in utc""" 

54 return calendar.timegm(datetime.datetime.now(datetime.timezone.utc).utctimetuple()) 

55 

56 

57def uts_to_date_utc(uts: int, tformat: str = "%Y-%m-%dT%H:%M:%SZ") -> str: 

58 """convert unix timestamp to date format""" 

59 return datetime.datetime.fromtimestamp(int(uts), tz=datetime.timezone.utc).strftime( 

60 tformat 

61 ) 

62 

63 

64def date_to_uts_utc(date_human: str, _tformat: str = "%Y-%m-%dT%H:%M:%S") -> int: 

65 """convert date to unix timestamp""" 

66 if isinstance(date_human, datetime.datetime): 

67 # we already got an datetime object as input 

68 result = calendar.timegm(date_human.timetuple()) 

69 else: 

70 result = int(calendar.timegm(parse(date_human).timetuple())) 

71 return result 

72 

73 

74def date_to_datestr( 

75 date: datetime.datetime, tformat: str = "%Y-%m-%dT%H:%M:%SZ" 

76) -> str: 

77 """convert dateobj to datestring""" 

78 try: 

79 result = date.strftime(tformat) 

80 except Exception: 

81 result = None 

82 return result 

83 

84 

85def datestr_to_date(datestr: str, tformat: str = "%Y-%m-%dT%H:%M:%S") -> str: 

86 """convert datestr to dateobj""" 

87 try: 

88 result = datetime.datetime.strptime(datestr, tformat) 

89 except Exception: 

90 result = None 

91 return result