Example #1
0
    def render(self, context):
        if self.boundfield is not None:
            if self.boundfield.field.disabled:
                self.label.attributes["_class"] += " bx--label--disabled"
            self.label.attributes["_for"] = self.boundfield.id_for_label
            self.label.append(self.boundfield.label)
            if not self.boundfield.field.required:
                self.label.append(_(" (optional)"))

            dateformat = (
                self.boundfield.field.widget.format
                or formats.get_format(self.boundfield.field.widget.format_key)[0]
            )
            dateformat_widget = to_php_formatstr(
                self.boundfield.field.widget.format,
                self.boundfield.field.widget.format_key,
            )
            if self.simple:
                self.input.attributes["pattern"] = TimeRE().compile(dateformat).pattern
            else:
                self.input.attributes["data_date_format"] = dateformat_widget

            if self.boundfield.help_text:
                self[0][0].append(HelperText(self.boundfield.help_text))
            if self.boundfield.errors:
                self.input.attributes["data-invalid"] = True
                self[1].append(
                    Icon(
                        "warning--filled",
                        size=16,
                        _class="bx--text-input__invalid-icon",
                    )
                )
                self[0][0].append(ErrorList(self.boundfield.errors))
        return super().render(context)
Example #2
0
def strpdate(data_string, format='%Y-%m-%d', bc=False):
    _TimeRE_cache = TimeRE()
    _regex_cache = {}
    try:
        format_regex = _TimeRE_cache.compile(format)
    # KeyError raised when a bad format is found; can be specified as
    # \\, in which case it was a stray % but with a space after it
    except KeyError as err:
        bad_directive = err.args[0]
        if bad_directive == "\\":
            bad_directive = "%"
        del err
        raise ValueError("'%s' is a bad directive in format '%s'" %
                         (bad_directive, format))
    # IndexError only occurs when the format string is "%"
    except IndexError:
        raise ValueError("stray %% in format '%s'" % format)
    _regex_cache[format] = format_regex
    found = format_regex.match(data_string)
    if not found:
        raise ValueError("time data %r does not match format %r" %
                         (data_string, format))
    if len(data_string) != found.end():
        raise ValueError("unconverted data remains: %s" %
                         data_string[found.end():])
    date = list(todaydatetuple())
    found_dict = found.groupdict()
    for group_key in found_dict.keys():
        if group_key == 'y':
            date[0] = int(found_dict['y'])
            if date[0] <= 68:
                date[0] += 2000
            else:
                date[0] += 1900
        elif group_key == 'Y':
            date[0] = int(found_dict['Y'])
        elif group_key == 'm':
            date[1] = int(found_dict['m'])
        elif group_key == 'd':
            date[2] = int(found_dict['d'])
    if not (bc and date == [1, 2, 29]):
        datetime(*date)
    return tuple(date)
Example #3
0
def _tokenize_datetime(dt, fmt):
    try:
        time_re = _tokenize_datetime._time_re
    except AttributeError:
        from _strptime import TimeRE  # Needed to work around timezone handling limitations
        time_re = _tokenize_datetime._time_re = TimeRE()
        time_re[
            'z'] = r'(?P<z>[+-]\d\d:?[0-5]\d)'  # Allow ':' in timezone offset notation
        time_re[
            'Z'] = r'(?P<Z>[0-9A-Za-z_/+-]+)'  # Allow any timezone possibly supported by pytz

    dt = str(dt)
    time_rx = time_re.compile(fmt)
    m = time_rx.match(dt)
    if not m:
        raise ValueError('time data {!r} does not match format {!r}'.format(
            dt, fmt))
    if len(dt) != m.end():
        raise ValueError('unconverted data remains: {}'.format(dt[m.end():]))
    return m.groupdict()
Example #4
0
TZ_ABBR_RE = r"[A-Z](?:[A-Z]{2,4})?"
FIXED_OFFSET_TZ_RE = re.compile(r"(%s)?([+-][01]\d(?::?\d{2})?)?$" % (TZ_ABBR_RE,))

def _getYearCentRE(cent=(0,3), distance=3, now=(MyTime.now(), MyTime.alternateNow)):
	""" Build century regex for last year and the next years (distance).
		
	Thereby respect possible run in the test-cases (alternate date used there)
	"""
	cent = lambda year, f=cent[0], t=cent[1]: str(year)[f:t]
	exprset = set( cent(now[0].year + i) for i in (-1, distance) )
	if len(now) and now[1]:
		exprset |= set( cent(now[1].year + i) for i in (-1, distance) )
	return "(?:%s)" % "|".join(exprset) if len(exprset) > 1 else "".join(exprset)

timeRE = TimeRE()

# %k - one- or two-digit number giving the hour of the day (0-23) on a 24-hour clock,
# (corresponds %H, but allows space if not zero-padded).
# %l - one- or two-digit number giving the hour of the day (12-11) on a 12-hour clock,
# (corresponds %I, but allows space if not zero-padded).
timeRE['k'] = r" ?(?P<H>[0-2]?\d)"
timeRE['l'] = r" ?(?P<I>1?\d)"

# TODO: because python currently does not support mixing of case-sensitive with case-insensitive matching,
#       check how TZ (in uppercase) can be combined with %a/%b etc. (that are currently case-insensitive), 
#       to avoid invalid date-time recognition in strings like '11-Aug-2013 03:36:11.372 error ...' 
#       with wrong TZ "error", which is at least not backwards compatible.
#       Hence %z currently match literal Z|UTC|GMT only (and offset-based), and %Exz - all zone abbreviations.
timeRE['Z'] = r"(?P<Z>Z|[A-Z]{3,5})"
timeRE['z'] = r"(?P<z>Z|UTC|GMT|[+-][01]\d(?::?\d{2})?)"
Example #5
0
    def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
        """Return a 2-tuple consisting of a time struct and an int containing
        the number of microseconds based on the input string and the
        format string."""

        for index, arg in enumerate([data_string, format]):
            if not isinstance(arg, str):
                msg = "strptime() argument {} must be str, not {}"
                raise TypeError(msg.format(index, type(arg)))

        global _TimeRE_cache, _regex_cache
        with _cache_lock:
            if _getlang() != _TimeRE_cache.locale_time.lang:
                _TimeRE_cache = TimeRE()
                _regex_cache.clear()
            if len(_regex_cache) > _CACHE_MAX_SIZE:
                _regex_cache.clear()
            locale_time = _TimeRE_cache.locale_time
            format_regex = _regex_cache.get(format)
            if not format_regex:
                try:
                    format_regex = _TimeRE_cache.compile(format)
                # KeyError raised when a bad format is found; can be specified as
                # \\, in which case it was a stray % but with a space after it
                except KeyError as err:
                    bad_directive = err.args[0]
                    if bad_directive == "\\":
                        bad_directive = "%"
                    del err
                    raise ValueError("'%s' is a bad directive in format '%s'" %
                                     (bad_directive, format))
                # IndexError only occurs when the format string is "%"
                except IndexError:
                    raise ValueError("stray %% in format '%s'" % format)
                _regex_cache[format] = format_regex
        found = format_regex.match(data_string)
        if not found:
            raise ValueError("time data %r does not match format %r" %
                             (data_string, format))
        if len(data_string) != found.end():
            raise ValueError("unconverted data remains: %s" %
                             data_string[found.end():])

        year = 1900
        month = day = 1
        hour = minute = second = fraction = 0
        tz = -1
        tzoffset = None
        # Default to -1 to signify that values not known; not critical to have,
        # though
        week_of_year = -1
        week_of_year_start = -1
        # weekday and julian defaulted to -1 so as to signal need to calculate
        # values
        weekday = julian = -1
        found_dict = found.groupdict()
        for group_key in found_dict.iterkeys():
            # Directives not explicitly handled below:
            #   c, x, X
            #      handled by making out of other directives
            #   U, W
            #      worthless without day of the week
            if group_key == 'y':
                year = int(found_dict['y'])
                # Open Group specification for strptime() states that a %y
                #value in the range of [00, 68] is in the century 2000, while
                #[69,99] is in the century 1900
                if year <= 68:
                    year += 2000
                else:
                    year += 1900
            elif group_key == 'Y':
                year = int(found_dict['Y'])
            elif group_key == 'm':
                month = int(found_dict['m'])
            elif group_key == 'B':
                month = locale_time.f_month.index(found_dict['B'].lower())
            elif group_key == 'b':
                month = locale_time.a_month.index(found_dict['b'].lower())
            elif group_key == 'd':
                day = int(found_dict['d'])
            elif group_key == 'H':
                hour = int(found_dict['H'])
            elif group_key == 'I':
                hour = int(found_dict['I'])
                ampm = found_dict.get('p', '').lower()
                # If there was no AM/PM indicator, we'll treat this like AM
                if ampm in ('', locale_time.am_pm[0]):
                    # We're in AM so the hour is correct unless we're
                    # looking at 12 midnight.
                    # 12 midnight == 12 AM == hour 0
                    if hour == 12:
                        hour = 0
                elif ampm == locale_time.am_pm[1]:
                    # We're in PM so we need to add 12 to the hour unless
                    # we're looking at 12 noon.
                    # 12 noon == 12 PM == hour 12
                    if hour != 12:
                        hour += 12
            elif group_key == 'M':
                minute = int(found_dict['M'])
            elif group_key == 'S':
                second = int(found_dict['S'])
            elif group_key == 'f':
                s = found_dict['f']
                # Pad to always return microseconds.
                s += "0" * (6 - len(s))
                fraction = int(s)
            elif group_key == 'A':
                weekday = locale_time.f_weekday.index(found_dict['A'].lower())
            elif group_key == 'a':
                weekday = locale_time.a_weekday.index(found_dict['a'].lower())
            elif group_key == 'w':
                weekday = int(found_dict['w'])
                if weekday == 0:
                    weekday = 6
                else:
                    weekday -= 1
            elif group_key == 'j':
                julian = int(found_dict['j'])
            elif group_key in ('U', 'W'):
                week_of_year = int(found_dict[group_key])
                if group_key == 'U':
                    # U starts week on Sunday.
                    week_of_year_start = 6
                else:
                    # W starts week on Monday.
                    week_of_year_start = 0
            elif group_key == 'z':
                z = found_dict['z']
                tzoffset = int(z[1:3]) * 60 + int(z[3:5])
                if z.startswith("-"):
                    tzoffset = -tzoffset
            elif group_key == 'Z':
                # Since -1 is default value only need to worry about setting tz if
                # it can be something other than -1.
                found_zone = found_dict['Z'].lower()
                for value, tz_values in enumerate(locale_time.timezone):
                    if found_zone in tz_values:
                        # Deal with bad locale setup where timezone names are the
                        # same and yet time.daylight is true; too ambiguous to
                        # be able to tell what timezone has daylight savings
                        if (time.tzname[0] == time.tzname[1] and time.daylight
                                and found_zone not in ("utc", "gmt")):
                            break
                        else:
                            tz = value
                            break
        # If we know the week of the year and what day of that week, we can figure
        # out the Julian day of the year.
        if julian == -1 and week_of_year != -1 and weekday != -1:
            week_starts_Mon = True if week_of_year_start == 0 else False
            julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
                                              week_starts_Mon)
        # Cannot pre-calculate datetime_date() since can change in Julian
        # calculation and thus could have different value for the day of the week
        # calculation.
        if julian == -1:
            # Need to add 1 to result since first day of the year is 1, not 0.
            julian = datetime_date(year, month, day).toordinal() - \
                      datetime_date(year, 1, 1).toordinal() + 1
        else:  # Assume that if they bothered to include Julian day it will
            # be accurate.
            datetime_result = datetime_date.fromordinal(
                (julian - 1) + datetime_date(year, 1, 1).toordinal())
            year = datetime_result.year
            month = datetime_result.month
            day = datetime_result.day
        if weekday == -1:
            weekday = datetime_date(year, month, day).weekday()
        # Add timezone info
        tzname = found_dict.get("Z")
        if tzoffset is not None:
            gmtoff = tzoffset * 60
        else:
            gmtoff = None

        return (year, month, day, hour, minute, second, weekday, julian, tz,
                gmtoff, tzname), fraction
Example #6
0
            while '%' in format:
                directive_index = format.index('%') + 1
                processed_format = "%s%s%s" % (processed_format,
                                               format[:directive_index - 1],
                                               self[format[directive_index]])
                format = format[directive_index + 1:]
            return "%s%s" % (processed_format, format)

        def compile(self, format):
            """Return a compiled re object for the format string."""
            return re_compile(self.pattern(format), IGNORECASE)

    _cache_lock = _thread_allocate_lock()
    # DO NOT modify _TimeRE_cache or _regex_cache without acquiring the cache lock
    # first!
    _TimeRE_cache = TimeRE()
    _CACHE_MAX_SIZE = 5  # Max number of regexes stored in _regex_cache
    _regex_cache = {}

    def _calc_julian_from_U_or_W(year, week_of_year, day_of_week,
                                 week_starts_Mon):
        """Calculate the Julian day based on the year, week of the year, and day of
        the week, with week_start_day representing whether the week of the year
        assumes the week starts on Sunday or Monday (6 or 0)."""
        first_weekday = datetime_date(year, 1, 1).weekday()
        # If we are dealing with the %U directive (week starts on Sunday), it's
        # easier to just shift the view to Sunday being the first day of the
        # week.
        if not week_starts_Mon:
            first_weekday = (first_weekday + 1) % 7
            day_of_week = (day_of_week + 1) % 7
Example #7
0
    def __init__(
        self,
        label=None,
        help_text=None,
        errors=None,
        inputelement_attrs=None,
        boundfield=None,
        style_short=False,
        style_simple=False,
        **attributes,
    ):
        inputelement_attrs = inputelement_attrs or {}

        def format_date_value(context):
            bfield = hg.resolve_lazy(boundfield, context)
            return bfield.field.widget.format_value(bfield.value())

        super().__init__(
            hg.DIV(
                label,
                hg.If(
                    style_simple,
                    self.get_input_element(
                        inputelement_attrs,
                        errors,
                        data_invalid=hg.If(getattr(errors, "condition"), True),
                        pattern=hg.F(lambda c: (TimeRE().compile(
                            hg.resolve_lazy(boundfield, c).field.widget.format
                            or formats.get_format(
                                hg.resolve_lazy(boundfield, c).field.widget.
                                format_key)[0]).pattern)),
                        value=hg.F(format_date_value),
                    ),
                    hg.DIV(
                        self.get_input_element(
                            inputelement_attrs,
                            errors,
                            data_date_picker_input=True,
                            data_invalid=hg.If(getattr(errors, "condition"),
                                               True),
                            data_date_format=hg.F(lambda c: to_php_formatstr(
                                hg.resolve_lazy(boundfield, c).field.widget.
                                format,
                                hg.resolve_lazy(boundfield, c
                                                ).field.widget.format_key,
                            )),
                            value=hg.F(format_date_value),
                        ),
                        Icon(
                            "calendar",
                            size=16,
                            _class="bx--date-picker__icon",
                            data_date_picker_icon="true",
                        ),
                        _class="bx--date-picker-input__wrapper",
                    ),
                ),
                help_text,
                errors,
                _class="bx--date-picker-container",
            ),
            **hg.merge_html_attrs(
                attributes,
                {
                    "data_date_picker":
                    not style_simple,
                    "data_date_picker_type":
                    None if style_simple else "single",
                    "_class":
                    hg.BaseElement(
                        "bx--date-picker",
                        hg.If(
                            style_simple,
                            " bx--date-picker--simple",
                            " bx--date-picker--single",
                        ),
                        hg.If(style_short, " bx--date-picker--short"),
                    ),
                },
            ),
        )
Example #8
0
def dateformatstr2regex(formatstr, format_key):
    formatstr = formatstr or formats.get_format(format_key)[0]
    # check: are local formats handled correctly?
    return TimeRE().compile(formatstr).pattern
Example #9
0
    def _strptime(data_string, format="%a %b %d %H:%M:%S %Y"):
        """Return a 2-tuple consisting of a time struct and an int containing
        the number of microseconds based on the input string and the
        format string."""

        for index, arg in enumerate([data_string, format]):
            if not isinstance(arg, str):
                msg = "strptime() argument {} must be str, not {}"
                raise TypeError(msg.format(index, type(arg)))

        global _TimeRE_cache, _regex_cache
        with _cache_lock:
            if _getlang() != _TimeRE_cache.locale_time.lang:
                _TimeRE_cache = TimeRE()
                _regex_cache.clear()
            if len(_regex_cache) > _CACHE_MAX_SIZE:
                _regex_cache.clear()
            locale_time = _TimeRE_cache.locale_time
            format_regex = _regex_cache.get(format)
            if not format_regex:
                try:
                    format_regex = _TimeRE_cache.compile(format)
                # KeyError raised when a bad format is found; can be specified as
                # \\, in which case it was a stray % but with a space after it
                except KeyError as err:
                    bad_directive = err.args[0]
                    if bad_directive == "\\":
                        bad_directive = "%"
                    del err
                    raise ValueError("'%s' is a bad directive in format '%s'" %
                                        (bad_directive, format))
                # IndexError only occurs when the format string is "%"
                except IndexError:
                    raise ValueError("stray %% in format '%s'" % format)
                _regex_cache[format] = format_regex
        found = format_regex.match(data_string)
        if not found:
            raise ValueError("time data %r does not match format %r" %
                             (data_string, format))
        if len(data_string) != found.end():
            raise ValueError("unconverted data remains: %s" %
                              data_string[found.end():])

        year = 1900
        month = day = 1
        hour = minute = second = fraction = 0
        tz = -1
        tzoffset = None
        # Default to -1 to signify that values not known; not critical to have,
        # though
        week_of_year = -1
        week_of_year_start = -1
        # weekday and julian defaulted to -1 so as to signal need to calculate
        # values
        weekday = julian = -1
        found_dict = found.groupdict()
        for group_key in found_dict.iterkeys():
            # Directives not explicitly handled below:
            #   c, x, X
            #      handled by making out of other directives
            #   U, W
            #      worthless without day of the week
            if group_key == 'y':
                year = int(found_dict['y'])
                # Open Group specification for strptime() states that a %y
                #value in the range of [00, 68] is in the century 2000, while
                #[69,99] is in the century 1900
                if year <= 68:
                    year += 2000
                else:
                    year += 1900
            elif group_key == 'Y':
                year = int(found_dict['Y'])
            elif group_key == 'm':
                month = int(found_dict['m'])
            elif group_key == 'B':
                month = locale_time.f_month.index(found_dict['B'].lower())
            elif group_key == 'b':
                month = locale_time.a_month.index(found_dict['b'].lower())
            elif group_key == 'd':
                day = int(found_dict['d'])
            elif group_key == 'H':
                hour = int(found_dict['H'])
            elif group_key == 'I':
                hour = int(found_dict['I'])
                ampm = found_dict.get('p', '').lower()
                # If there was no AM/PM indicator, we'll treat this like AM
                if ampm in ('', locale_time.am_pm[0]):
                    # We're in AM so the hour is correct unless we're
                    # looking at 12 midnight.
                    # 12 midnight == 12 AM == hour 0
                    if hour == 12:
                        hour = 0
                elif ampm == locale_time.am_pm[1]:
                    # We're in PM so we need to add 12 to the hour unless
                    # we're looking at 12 noon.
                    # 12 noon == 12 PM == hour 12
                    if hour != 12:
                        hour += 12
            elif group_key == 'M':
                minute = int(found_dict['M'])
            elif group_key == 'S':
                second = int(found_dict['S'])
            elif group_key == 'f':
                s = found_dict['f']
                # Pad to always return microseconds.
                s += "0" * (6 - len(s))
                fraction = int(s)
            elif group_key == 'A':
                weekday = locale_time.f_weekday.index(found_dict['A'].lower())
            elif group_key == 'a':
                weekday = locale_time.a_weekday.index(found_dict['a'].lower())
            elif group_key == 'w':
                weekday = int(found_dict['w'])
                if weekday == 0:
                    weekday = 6
                else:
                    weekday -= 1
            elif group_key == 'j':
                julian = int(found_dict['j'])
            elif group_key in ('U', 'W'):
                week_of_year = int(found_dict[group_key])
                if group_key == 'U':
                    # U starts week on Sunday.
                    week_of_year_start = 6
                else:
                    # W starts week on Monday.
                    week_of_year_start = 0
            elif group_key == 'z':
                z = found_dict['z']
                tzoffset = int(z[1:3]) * 60 + int(z[3:5])
                if z.startswith("-"):
                    tzoffset = -tzoffset
            elif group_key == 'Z':
                # Since -1 is default value only need to worry about setting tz if
                # it can be something other than -1.
                found_zone = found_dict['Z'].lower()
                for value, tz_values in enumerate(locale_time.timezone):
                    if found_zone in tz_values:
                        # Deal with bad locale setup where timezone names are the
                        # same and yet time.daylight is true; too ambiguous to
                        # be able to tell what timezone has daylight savings
                        if (time.tzname[0] == time.tzname[1] and
                           time.daylight and found_zone not in ("utc", "gmt")):
                            break
                        else:
                            tz = value
                            break
        # If we know the week of the year and what day of that week, we can figure
        # out the Julian day of the year.
        if julian == -1 and week_of_year != -1 and weekday != -1:
            week_starts_Mon = True if week_of_year_start == 0 else False
            julian = _calc_julian_from_U_or_W(year, week_of_year, weekday,
                                                week_starts_Mon)
        # Cannot pre-calculate datetime_date() since can change in Julian
        # calculation and thus could have different value for the day of the week
        # calculation.
        if julian == -1:
            # Need to add 1 to result since first day of the year is 1, not 0.
            julian = datetime_date(year, month, day).toordinal() - \
                      datetime_date(year, 1, 1).toordinal() + 1
        else:  # Assume that if they bothered to include Julian day it will
               # be accurate.
            datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal())
            year = datetime_result.year
            month = datetime_result.month
            day = datetime_result.day
        if weekday == -1:
            weekday = datetime_date(year, month, day).weekday()
        # Add timezone info
        tzname = found_dict.get("Z")
        if tzoffset is not None:
            gmtoff = tzoffset * 60
        else:
            gmtoff = None

        return (year, month, day,
                hour, minute, second,
                weekday, julian, tz, gmtoff, tzname), fraction