def parse_date()

in visualizeConnectData/lambdas/modifyCTR/isodate/isodates.py [0:0]


def parse_date(
        datestring,
        yeardigits=4, expanded=False, defaultmonth=1, defaultday=1):
    '''
    Parse an ISO 8601 date string into a datetime.date object.

    As the datetime.date implementation is limited to dates starting from
    0001-01-01, negative dates (BC) and year 0 can not be parsed by this
    method.

    For incomplete dates, this method chooses the first day for it. For
    instance if only a century is given, this method returns the 1st of
    January in year 1 of this century.

    supported formats: (expanded formats are shown with 6 digits for year)
      YYYYMMDD    +-YYYYYYMMDD      basic complete date
      YYYY-MM-DD  +-YYYYYY-MM-DD    extended complete date
      YYYYWwwD    +-YYYYYYWwwD      basic complete week date
      YYYY-Www-D  +-YYYYYY-Www-D    extended complete week date
      YYYYDDD     +-YYYYYYDDD       basic ordinal date
      YYYY-DDD    +-YYYYYY-DDD      extended ordinal date
      YYYYWww     +-YYYYYYWww       basic incomplete week date
      YYYY-Www    +-YYYYYY-Www      extended incomplete week date
      YYYMM       +-YYYYYYMM        basic incomplete month date
      YYY-MM      +-YYYYYY-MM       incomplete month date
      YYYY        +-YYYYYY          incomplete year date
      YY          +-YYYY            incomplete century date

    @param datestring: the ISO date string to parse
    @param yeardigits: how many digits are used to represent a year
    @param expanded: if True then +/- signs are allowed. This parameter
                     is forced to True, if yeardigits != 4

    @return: a datetime.date instance represented by datestring
    @raise ISO8601Error: if this function can not parse the datestring
    @raise ValueError: if datestring can not be represented by datetime.date
    '''
    if yeardigits != 4:
        expanded = True
    isodates = build_date_regexps(yeardigits, expanded)
    for pattern in isodates:
        match = pattern.match(datestring)
        if match:
            groups = match.groupdict()
            # sign, century, year, month, week, day,
            # FIXME: negative dates not possible with python standard types
            sign = (groups['sign'] == '-' and -1) or 1
            if 'century' in groups:
                return date(
                    sign * (int(groups['century']) * 100 + 1),
                    defaultmonth, defaultday)
            if 'month' not in groups:  # weekdate or ordinal date
                ret = date(sign * int(groups['year']), 1, 1)
                if 'week' in groups:
                    isotuple = ret.isocalendar()
                    if 'day' in groups:
                        days = int(groups['day'] or 1)
                    else:
                        days = 1
                    # if first week in year, do weeks-1
                    return ret + timedelta(weeks=int(groups['week']) -
                                           (((isotuple[1] == 1) and 1) or 0),
                                           days=-isotuple[2] + days)
                elif 'day' in groups:  # ordinal date
                    return ret + timedelta(days=int(groups['day']) - 1)
                else:  # year date
                    return ret.replace(month=defaultmonth, day=defaultday)
            # year-, month-, or complete date
            if 'day' not in groups or groups['day'] is None:
                day = defaultday
            else:
                day = int(groups['day'])
            return date(sign * int(groups['year']),
                        int(groups['month']) or defaultmonth, day)
    raise ISO8601Error('Unrecognised ISO 8601 date format: %r' % datestring)