Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/aniso8601/date.py: 83%

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

75 statements  

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

2 

3# Copyright (c) 2021, Brandon Nielsen 

4# All rights reserved. 

5# 

6# This software may be modified and distributed under the terms 

7# of the BSD license. See the LICENSE file for details. 

8 

9from aniso8601.builders import TupleBuilder 

10from aniso8601.builders.python import PythonTimeBuilder 

11from aniso8601.compat import is_string 

12from aniso8601.exceptions import ISOFormatError 

13from aniso8601.resolution import DateResolution 

14 

15 

16def get_date_resolution(isodatestr): 

17 # Valid string formats are: 

18 # 

19 # Y[YYY] 

20 # YYYY-MM-DD 

21 # YYYYMMDD 

22 # YYYY-MM 

23 # YYYY-Www 

24 # YYYYWww 

25 # YYYY-Www-D 

26 # YYYYWwwD 

27 # YYYY-DDD 

28 # YYYYDDD 

29 isodatetuple = parse_date(isodatestr, builder=TupleBuilder) 

30 

31 if isodatetuple.DDD is not None: 

32 # YYYY-DDD 

33 # YYYYDDD 

34 return DateResolution.Ordinal 

35 

36 if isodatetuple.D is not None: 

37 # YYYY-Www-D 

38 # YYYYWwwD 

39 return DateResolution.Weekday 

40 

41 if isodatetuple.Www is not None: 

42 # YYYY-Www 

43 # YYYYWww 

44 return DateResolution.Week 

45 

46 if isodatetuple.DD is not None: 

47 # YYYY-MM-DD 

48 # YYYYMMDD 

49 return DateResolution.Day 

50 

51 if isodatetuple.MM is not None: 

52 # YYYY-MM 

53 return DateResolution.Month 

54 

55 # Y[YYY] 

56 return DateResolution.Year 

57 

58 

59def parse_date(isodatestr, builder=PythonTimeBuilder): 

60 # Given a string in any ISO 8601 date format, return a datetime.date 

61 # object that corresponds to the given date. Valid string formats are: 

62 # 

63 # Y[YYY] 

64 # YYYY-MM-DD 

65 # YYYYMMDD 

66 # YYYY-MM 

67 # YYYY-Www 

68 # YYYYWww 

69 # YYYY-Www-D 

70 # YYYYWwwD 

71 # YYYY-DDD 

72 # YYYYDDD 

73 if is_string(isodatestr) is False: 

74 raise ValueError("Date must be string.") 

75 

76 if isodatestr.startswith("+") or isodatestr.startswith("-"): 

77 raise NotImplementedError( 

78 "ISO 8601 extended year representation " "not supported." 

79 ) 

80 

81 if len(isodatestr) == 0 or isodatestr.count("-") > 2: 

82 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr)) 

83 

84 yearstr = None 

85 monthstr = None 

86 daystr = None 

87 weekstr = None 

88 weekdaystr = None 

89 ordinaldaystr = None 

90 

91 if len(isodatestr) <= 4: 

92 # Y[YYY] 

93 yearstr = isodatestr 

94 elif "W" in isodatestr: 

95 if len(isodatestr) == 10: 

96 # YYYY-Www-D 

97 yearstr = isodatestr[0:4] 

98 weekstr = isodatestr[6:8] 

99 weekdaystr = isodatestr[9] 

100 elif len(isodatestr) == 8: 

101 if "-" in isodatestr: 

102 # YYYY-Www 

103 yearstr = isodatestr[0:4] 

104 weekstr = isodatestr[6:] 

105 else: 

106 # YYYYWwwD 

107 yearstr = isodatestr[0:4] 

108 weekstr = isodatestr[5:7] 

109 weekdaystr = isodatestr[7] 

110 elif len(isodatestr) == 7: 

111 # YYYYWww 

112 yearstr = isodatestr[0:4] 

113 weekstr = isodatestr[5:] 

114 elif len(isodatestr) == 7: 

115 if "-" in isodatestr: 

116 # YYYY-MM 

117 yearstr = isodatestr[0:4] 

118 monthstr = isodatestr[5:] 

119 else: 

120 # YYYYDDD 

121 yearstr = isodatestr[0:4] 

122 ordinaldaystr = isodatestr[4:] 

123 elif len(isodatestr) == 8: 

124 if "-" in isodatestr: 

125 # YYYY-DDD 

126 yearstr = isodatestr[0:4] 

127 ordinaldaystr = isodatestr[5:] 

128 else: 

129 # YYYYMMDD 

130 yearstr = isodatestr[0:4] 

131 monthstr = isodatestr[4:6] 

132 daystr = isodatestr[6:] 

133 elif len(isodatestr) == 10: 

134 # YYYY-MM-DD 

135 yearstr = isodatestr[0:4] 

136 monthstr = isodatestr[5:7] 

137 daystr = isodatestr[8:] 

138 else: 

139 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr)) 

140 

141 hascomponent = False 

142 

143 for componentstr in [yearstr, monthstr, daystr, weekstr, weekdaystr, ordinaldaystr]: 

144 if componentstr is not None: 

145 hascomponent = True 

146 

147 if componentstr.isdigit() is False: 

148 raise ISOFormatError( 

149 '"{0}" is not a valid ISO 8601 date.'.format(isodatestr) 

150 ) 

151 

152 if hascomponent is False: 

153 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr)) 

154 

155 return builder.build_date( 

156 YYYY=yearstr, 

157 MM=monthstr, 

158 DD=daystr, 

159 Www=weekstr, 

160 D=weekdaystr, 

161 DDD=ordinaldaystr, 

162 )