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
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) 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.
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 # 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.")
76 if isodatestr.startswith("+") or isodatestr.startswith("-"):
77 raise NotImplementedError(
78 "ISO 8601 extended year representation " "not supported."
79 )
81 if len(isodatestr) == 0 or isodatestr.count("-") > 2:
82 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
84 yearstr = None
85 monthstr = None
86 daystr = None
87 weekstr = None
88 weekdaystr = None
89 ordinaldaystr = None
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))
141 hascomponent = False
143 for componentstr in [yearstr, monthstr, daystr, weekstr, weekdaystr, ordinaldaystr]:
144 if componentstr is not None:
145 hascomponent = True
147 if componentstr.isdigit() is False:
148 raise ISOFormatError(
149 '"{0}" is not a valid ISO 8601 date.'.format(isodatestr)
150 )
152 if hascomponent is False:
153 raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
155 return builder.build_date(
156 YYYY=yearstr,
157 MM=monthstr,
158 DD=daystr,
159 Www=weekstr,
160 D=weekdaystr,
161 DDD=ordinaldaystr,
162 )