Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/aniso8601/date.py: 9%
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) 2025, 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.
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
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)
31 if isodatetuple.DDD is not None:
32 # YYYY-DDD
33 # YYYYDDD
34 return DateResolution.Ordinal
36 if isodatetuple.D is not None:
37 # YYYY-Www-D
38 # YYYYWwwD
39 return DateResolution.Weekday
41 if isodatetuple.Www is not None:
42 # YYYY-Www
43 # YYYYWww
44 return DateResolution.Week
46 if isodatetuple.DD is not None:
47 # YYYY-MM-DD
48 # YYYYMMDD
49 return DateResolution.Day
51 if isodatetuple.MM is not None:
52 # YYYY-MM
53 return DateResolution.Month
55 # Y[YYY]
56 return DateResolution.Year
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 # YY
64 # YYYY
65 # YYYY-MM-DD
66 # YYYYMMDD
67 # YYYY-MM
68 # YYYY-Www
69 # YYYYWww
70 # YYYY-Www-D
71 # YYYYWwwD
72 # YYYY-DDD
73 # YYYYDDD
74 if is_string(isodatestr) is False:
75 raise ValueError("Date must be string.")
77 if isodatestr.startswith("+") or isodatestr.startswith("-"):
78 raise NotImplementedError(
79 "ISO 8601 extended year representation not supported."
80 )
82 if len(isodatestr) == 0 or isodatestr.count("-") > 2:
83 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
85 yearstr = None
86 monthstr = None
87 daystr = None
88 weekstr = None
89 weekdaystr = None
90 ordinaldaystr = None
92 if len(isodatestr) in (2, 4):
93 # YY
94 # YYYY
95 yearstr = isodatestr
96 elif "W" in isodatestr:
97 if len(isodatestr) == 10:
98 # YYYY-Www-D
99 yearstr = isodatestr[0:4]
100 weekstr = isodatestr[6:8]
101 weekdaystr = isodatestr[9]
102 elif len(isodatestr) == 8:
103 if "-" in isodatestr:
104 # YYYY-Www
105 yearstr = isodatestr[0:4]
106 weekstr = isodatestr[6:]
107 else:
108 # YYYYWwwD
109 yearstr = isodatestr[0:4]
110 weekstr = isodatestr[5:7]
111 weekdaystr = isodatestr[7]
112 elif len(isodatestr) == 7:
113 # YYYYWww
114 yearstr = isodatestr[0:4]
115 weekstr = isodatestr[5:]
116 elif len(isodatestr) == 7:
117 if "-" in isodatestr:
118 # YYYY-MM
119 yearstr = isodatestr[0:4]
120 monthstr = isodatestr[5:]
121 else:
122 # YYYYDDD
123 yearstr = isodatestr[0:4]
124 ordinaldaystr = isodatestr[4:]
125 elif len(isodatestr) == 8:
126 if "-" in isodatestr:
127 # YYYY-DDD
128 yearstr = isodatestr[0:4]
129 ordinaldaystr = isodatestr[5:]
130 else:
131 # YYYYMMDD
132 yearstr = isodatestr[0:4]
133 monthstr = isodatestr[4:6]
134 daystr = isodatestr[6:]
135 elif len(isodatestr) == 10:
136 # YYYY-MM-DD
137 yearstr = isodatestr[0:4]
138 monthstr = isodatestr[5:7]
139 daystr = isodatestr[8:]
140 else:
141 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
143 hascomponent = False
145 for componentstr in [yearstr, monthstr, daystr, weekstr, weekdaystr, ordinaldaystr]:
146 if componentstr is not None:
147 hascomponent = True
149 if componentstr.isdigit() is False:
150 raise ISOFormatError(
151 '"{0}" is not a valid ISO 8601 date.'.format(isodatestr)
152 )
154 if hascomponent is False:
155 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
157 return builder.build_date(
158 YYYY=yearstr,
159 MM=monthstr,
160 DD=daystr,
161 Www=weekstr,
162 D=weekdaystr,
163 DDD=ordinaldaystr,
164 )