You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
# -*- coding: utf-8 -*-
# Copyright (c) 2021, Brandon Nielsen # All rights reserved. # # This software may be modified and distributed under the terms # of the BSD license. See the LICENSE file for details.
from aniso8601.builders import TupleBuilder from aniso8601.builders.python import PythonTimeBuilder from aniso8601.compat import is_string from aniso8601.exceptions import ISOFormatError from aniso8601.resolution import DateResolution
def get_date_resolution(isodatestr): # Valid string formats are: # # Y[YYY] # YYYY-MM-DD # YYYYMMDD # YYYY-MM # YYYY-Www # YYYYWww # YYYY-Www-D # YYYYWwwD # YYYY-DDD # YYYYDDD isodatetuple = parse_date(isodatestr, builder=TupleBuilder)
if isodatetuple.DDD is not None: # YYYY-DDD # YYYYDDD return DateResolution.Ordinal
if isodatetuple.D is not None: # YYYY-Www-D # YYYYWwwD return DateResolution.Weekday
if isodatetuple.Www is not None: # YYYY-Www # YYYYWww return DateResolution.Week
if isodatetuple.DD is not None: # YYYY-MM-DD # YYYYMMDD return DateResolution.Day
if isodatetuple.MM is not None: # YYYY-MM return DateResolution.Month
# Y[YYY] return DateResolution.Year
def parse_date(isodatestr, builder=PythonTimeBuilder): # Given a string in any ISO 8601 date format, return a datetime.date # object that corresponds to the given date. Valid string formats are: # # Y[YYY] # YYYY-MM-DD # YYYYMMDD # YYYY-MM # YYYY-Www # YYYYWww # YYYY-Www-D # YYYYWwwD # YYYY-DDD # YYYYDDD if is_string(isodatestr) is False: raise ValueError("Date must be string.")
if isodatestr.startswith("+") or isodatestr.startswith("-"): raise NotImplementedError( "ISO 8601 extended year representation " "not supported." )
if len(isodatestr) == 0 or isodatestr.count("-") > 2: raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr)) yearstr = None monthstr = None daystr = None weekstr = None weekdaystr = None ordinaldaystr = None
if len(isodatestr) <= 4: # Y[YYY] yearstr = isodatestr elif "W" in isodatestr: if len(isodatestr) == 10: # YYYY-Www-D yearstr = isodatestr[0:4] weekstr = isodatestr[6:8] weekdaystr = isodatestr[9] elif len(isodatestr) == 8: if "-" in isodatestr: # YYYY-Www yearstr = isodatestr[0:4] weekstr = isodatestr[6:] else: # YYYYWwwD yearstr = isodatestr[0:4] weekstr = isodatestr[5:7] weekdaystr = isodatestr[7] elif len(isodatestr) == 7: # YYYYWww yearstr = isodatestr[0:4] weekstr = isodatestr[5:] elif len(isodatestr) == 7: if "-" in isodatestr: # YYYY-MM yearstr = isodatestr[0:4] monthstr = isodatestr[5:] else: # YYYYDDD yearstr = isodatestr[0:4] ordinaldaystr = isodatestr[4:] elif len(isodatestr) == 8: if "-" in isodatestr: # YYYY-DDD yearstr = isodatestr[0:4] ordinaldaystr = isodatestr[5:] else: # YYYYMMDD yearstr = isodatestr[0:4] monthstr = isodatestr[4:6] daystr = isodatestr[6:] elif len(isodatestr) == 10: # YYYY-MM-DD yearstr = isodatestr[0:4] monthstr = isodatestr[5:7] daystr = isodatestr[8:] else: raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
hascomponent = False
for componentstr in [yearstr, monthstr, daystr, weekstr, weekdaystr, ordinaldaystr]: if componentstr is not None: hascomponent = True
if componentstr.isdigit() is False: raise ISOFormatError( '"{0}" is not a valid ISO 8601 date.'.format(isodatestr) )
if hascomponent is False: raise ISOFormatError('"{0}" is not a valid ISO 8601 date.'.format(isodatestr))
return builder.build_date( YYYY=yearstr, MM=monthstr, DD=daystr, Www=weekstr, D=weekdaystr, DDD=ordinaldaystr, )
|