Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/aniso8601/date.py: 82%
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
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
1# -*- coding: utf-8 -*-
3# Copyright (c) 2026, Brandon Nielsen
4# SPDX-License-Identifier: BSD-3-Clause
6from aniso8601.builders import TupleBuilder
7from aniso8601.builders.python import PythonTimeBuilder
8from aniso8601.compat import is_string
9from aniso8601.exceptions import ISOFormatError
10from aniso8601.resolution import DateResolution
13def get_date_resolution(isodatestr):
14 # Valid string formats are:
15 #
16 # Y[YYY]
17 # YYYY-MM-DD
18 # YYYYMMDD
19 # YYYY-MM
20 # YYYY-Www
21 # YYYYWww
22 # YYYY-Www-D
23 # YYYYWwwD
24 # YYYY-DDD
25 # YYYYDDD
26 isodatetuple = parse_date(isodatestr, builder=TupleBuilder)
28 if isodatetuple.DDD is not None:
29 # YYYY-DDD
30 # YYYYDDD
31 return DateResolution.Ordinal
33 if isodatetuple.D is not None:
34 # YYYY-Www-D
35 # YYYYWwwD
36 return DateResolution.Weekday
38 if isodatetuple.Www is not None:
39 # YYYY-Www
40 # YYYYWww
41 return DateResolution.Week
43 if isodatetuple.DD is not None:
44 # YYYY-MM-DD
45 # YYYYMMDD
46 return DateResolution.Day
48 if isodatetuple.MM is not None:
49 # YYYY-MM
50 return DateResolution.Month
52 # Y[YYY]
53 return DateResolution.Year
56def parse_date(isodatestr, builder=PythonTimeBuilder):
57 # Given a string in any ISO 8601 date format, return a datetime.date
58 # object that corresponds to the given date. Valid string formats are:
59 #
60 # YY
61 # YYYY
62 # YYYY-MM-DD
63 # YYYYMMDD
64 # YYYY-MM
65 # YYYY-Www
66 # YYYYWww
67 # YYYY-Www-D
68 # YYYYWwwD
69 # YYYY-DDD
70 # YYYYDDD
71 if is_string(isodatestr) is False:
72 raise ValueError("Date must be string.")
74 if isodatestr.startswith("+") or isodatestr.startswith("-"):
75 raise NotImplementedError(
76 "ISO 8601 extended year representation not supported."
77 )
79 if len(isodatestr) == 0 or isodatestr.count("-") > 2:
80 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
82 yearstr = None
83 monthstr = None
84 daystr = None
85 weekstr = None
86 weekdaystr = None
87 ordinaldaystr = None
89 if len(isodatestr) in (2, 4):
90 # YY
91 # YYYY
92 yearstr = isodatestr
93 elif "W" in isodatestr:
94 if len(isodatestr) == 10:
95 # YYYY-Www-D
96 yearstr = isodatestr[0:4]
97 weekstr = isodatestr[6:8]
98 weekdaystr = isodatestr[9]
99 elif len(isodatestr) == 8:
100 if "-" in isodatestr:
101 # YYYY-Www
102 yearstr = isodatestr[0:4]
103 weekstr = isodatestr[6:]
104 else:
105 # YYYYWwwD
106 yearstr = isodatestr[0:4]
107 weekstr = isodatestr[5:7]
108 weekdaystr = isodatestr[7]
109 elif len(isodatestr) == 7:
110 # YYYYWww
111 yearstr = isodatestr[0:4]
112 weekstr = isodatestr[5:]
113 elif len(isodatestr) == 7:
114 if "-" in isodatestr:
115 # YYYY-MM
116 yearstr = isodatestr[0:4]
117 monthstr = isodatestr[5:]
118 else:
119 # YYYYDDD
120 yearstr = isodatestr[0:4]
121 ordinaldaystr = isodatestr[4:]
122 elif len(isodatestr) == 8:
123 if "-" in isodatestr:
124 # YYYY-DDD
125 yearstr = isodatestr[0:4]
126 ordinaldaystr = isodatestr[5:]
127 else:
128 # YYYYMMDD
129 yearstr = isodatestr[0:4]
130 monthstr = isodatestr[4:6]
131 daystr = isodatestr[6:]
132 elif len(isodatestr) == 10:
133 # YYYY-MM-DD
134 yearstr = isodatestr[0:4]
135 monthstr = isodatestr[5:7]
136 daystr = isodatestr[8:]
137 else:
138 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
140 hascomponent = False
142 for componentstr in [yearstr, monthstr, daystr, weekstr, weekdaystr, ordinaldaystr]:
143 if componentstr is not None:
144 hascomponent = True
146 if componentstr.isdigit() is False:
147 raise ISOFormatError(
148 '"{0}" is not a valid ISO 8601 date.'.format(isodatestr)
149 )
151 if hascomponent is False:
152 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
154 return builder.build_date(
155 YYYY=yearstr,
156 MM=monthstr,
157 DD=daystr,
158 Www=weekstr,
159 D=weekdaystr,
160 DDD=ordinaldaystr,
161 )