예제 #1
0
파일: primitives.py 프로젝트: jab/lektor-1
    def value_from_raw(self, raw):
        if raw.value is None:
            return raw.missing_value('Missing datetime')
        try:
            chunks = raw.value.split(' ')
            date_info = [int(bit) for bit in chunks[0].split('-')]
            time_info = [int(bit) for bit in chunks[1].split(':')]
            datetime_info = date_info + time_info
            result = datetime(*datetime_info)

            if len(chunks) > 2:
                try:
                    tz = get_timezone(chunks[-1])
                except LookupError:
                    if len(chunks[-1]) > 5:
                        chunks[-1] = chunks[-1][-5:]
                    delta = int(chunks[-1][1:3]) * 60 + int(chunks[-1][3:])
                    if chunks[-1][0] == '-':
                        delta *= -1
                    tz = FixedOffset(delta)
                return tz.localize(result)

            return result
        except Exception:
            return raw.bad_value('Bad date format')
예제 #2
0
    def value_from_raw(self, raw):
        if raw.value is None:
            return raw.missing_value('Missing datetime')
        try:
            chunks = raw.value.split(' ')
            date_info = [int(bit) for bit in chunks[0].split('-')]
            time_info = [int(bit) for bit in chunks[1].split(':')]
            datetime_info = date_info + time_info
            result = datetime(*datetime_info)

            if len(chunks) > 2:
                try:
                    tz = get_timezone(chunks[-1])
                except LookupError:
                    if len(chunks[-1]) > 5:
                        chunks[-1] = chunks[-1][-5:]
                    delta = int(chunks[-1][1:3]) * 60 + int(chunks[-1][3:])
                    if chunks[-1][0] == '-':
                        delta *= -1
                    tz = FixedOffset(delta)
                return tz.localize(result)

            return result
        except Exception:
            return raw.bad_value('Bad date format')
예제 #3
0
def convert_to_datetime(input, tz, arg_name):
    """
    Converts the given object to a timezone aware datetime object.

    If a timezone aware datetime object is passed, it is returned unmodified.
    If a native datetime object is passed, it is given the specified timezone.
    If the input is a string, it is parsed as a datetime with the given timezone.

    Date strings are accepted in three different forms: date only (Y-m-d), date with time
    (Y-m-d H:M:S) or with date+time with microseconds (Y-m-d H:M:S.micro). Additionally you can
    override the time zone by giving a specific offset in the format specified by ISO 8601:
    Z (UTC), +HH:MM or -HH:MM.

    :param str|datetime input: the datetime or string to convert to a timezone aware datetime
    :param datetime.tzinfo tz: timezone to interpret ``input`` in
    :param str arg_name: the name of the argument (used in an error message)
    :rtype: datetime

    """
    if input is None:
        return
    elif isinstance(input, datetime):
        datetime_ = input
    elif isinstance(input, date):
        datetime_ = datetime.combine(input, time())
    elif isinstance(input, six.string_types):
        m = _DATE_REGEX.match(input)
        if not m:
            raise ValueError('Invalid date string')

        values = m.groupdict()
        tzname = values.pop('timezone')
        if tzname == 'Z':
            tz = utc
        elif tzname:
            hours, minutes = (int(x) for x in tzname[1:].split(':'))
            sign = 1 if tzname[0] == '+' else -1
            tz = FixedOffset(sign * (hours * 60 + minutes))

        values = {k: int(v or 0) for k, v in values.items()}
        datetime_ = datetime(**values)
    else:
        raise TypeError('Unsupported type for %s: %s' %
                        (arg_name, input.__class__.__name__))

    if datetime_.tzinfo is not None:
        return datetime_
    if tz is None:
        raise ValueError(
            'The "tz" argument must be specified if %s has no timezone information'
            % arg_name)
    if isinstance(tz, six.string_types):
        tz = timezone(tz)

    try:
        return tz.localize(datetime_, is_dst=None)
    except AttributeError:
        raise TypeError(
            'Only pytz timezones are supported (need the localize() and normalize() methods)'
        )
예제 #4
0
def hydrate_datetime(seconds, nanoseconds, tz=None):
    """ Hydrator for `DateTime` and `LocalDateTime` values.

    :param seconds:
    :param nanoseconds:
    :param tz:
    :return: datetime
    """
    microseconds, nanoseconds = divmod(nanoseconds, 1000)
    if nanoseconds != 0:
        warn(
            "Nanosecond resolution is not available on this platform, value is truncated at microsecond resolution"
        )
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)
    days, hours = divmod(hours, 24)
    t = datetime.combine(UNIX_EPOCH_DATE + timedelta(days=days),
                         time(hours, minutes, seconds, microseconds))
    if tz is None:
        return t
    if isinstance(tz, int):
        tz_offset_minutes, tz_offset_seconds = divmod(tz, 60)
        zone = FixedOffset(tz_offset_minutes)
    else:
        zone = timezone(tz)
    return zone.localize(t)
예제 #5
0
파일: util.py 프로젝트: hcwnbs/small
def convert_to_datetime(input, tz, arg_name):
    """
    Converts the given object to a timezone aware datetime object.

    If a timezone aware datetime object is passed, it is returned unmodified.
    If a native datetime object is passed, it is given the specified timezone.
    If the input is a string, it is parsed as a datetime with the given timezone.

    Date strings are accepted in three different forms: date only (Y-m-d), date with time
    (Y-m-d H:M:S) or with date+time with microseconds (Y-m-d H:M:S.micro). Additionally you can
    override the time zone by giving a specific offset in the format specified by ISO 8601:
    Z (UTC), +HH:MM or -HH:MM.

    :param str|datetime input: the datetime or string to convert to a timezone aware datetime
    :param datetime.tzinfo tz: timezone to interpret ``input`` in
    :param str arg_name: the name of the argument (used in an error message)
    :rtype: datetime

    """
    if input is None:
        return
    elif isinstance(input, datetime):
        datetime_ = input
    elif isinstance(input, date):
        datetime_ = datetime.combine(input, time())
    elif isinstance(input, six.string_types):
        m = _DATE_REGEX.match(input)
        if not m:
            raise ValueError('Invalid date string')

        values = m.groupdict()
        tzname = values.pop('timezone')
        if tzname == 'Z':
            tz = utc
        elif tzname:
            hours, minutes = (int(x) for x in tzname[1:].split(':'))
            sign = 1 if tzname[0] == '+' else -1
            tz = FixedOffset(sign * (hours * 60 + minutes))

        values = {k: int(v or 0) for k, v in values.items()}
        datetime_ = datetime(**values)
    else:
        raise TypeError('Unsupported type for %s: %s' % (arg_name, input.__class__.__name__))

    if datetime_.tzinfo is not None:
        return datetime_
    if tz is None:
        raise ValueError(
            'The "tz" argument must be specified if %s has no timezone information' % arg_name)
    if isinstance(tz, six.string_types):
        tz = timezone(tz)

    try:
        return tz.localize(datetime_, is_dst=None)
    except AttributeError:
        raise TypeError(
            'Only pytz timezones are supported (need the localize() and normalize() methods)')
예제 #6
0
    def _hydrate_time(self, nanoseconds, tz=None):
        """ Hydrator for `Time` and `LocalTime` values.

        :param nanoseconds:
        :param tz:
        :return: Time
        """
        seconds, nanoseconds = map(int, divmod(nanoseconds, 1000000000))
        minutes, seconds = map(int, divmod(seconds, 60))
        hours, minutes = map(int, divmod(minutes, 60))
        seconds = (1000000000 * seconds + nanoseconds) / 1000000000
        t = Time(hours, minutes, seconds)
        if tz is None:
            return t
        tz_offset_minutes, tz_offset_seconds = divmod(tz, 60)
        zone = FixedOffset(tz_offset_minutes)
        return zone.localize(t)
예제 #7
0
def hydrate_datetime(seconds, nanoseconds, tz=None):
    """ Hydrator for `DateTime` and `LocalDateTime` values.

    :param seconds:
    :param nanoseconds:
    :param tz:
    :return: datetime
    """
    minutes, seconds = map(int, divmod(seconds, 60))
    hours, minutes = map(int, divmod(minutes, 60))
    days, hours = map(int, divmod(hours, 24))
    seconds = (1000000000 * seconds + nanoseconds) / 1000000000
    t = DateTime.combine(UNIX_EPOCH_DATE_ORDINAL + days, Time(hours, minutes, seconds))
    if tz is None:
        return t
    if isinstance(tz, int):
        tz_offset_minutes, tz_offset_seconds = divmod(tz, 60)
        zone = FixedOffset(tz_offset_minutes)
    else:
        zone = timezone(tz)
    return zone.localize(t)
예제 #8
0
def hydrate_time(nanoseconds, tz=None):
    """ Hydrator for `Time` and `LocalTime` values.

    :param nanoseconds:
    :param tz:
    :return: time
    """
    microseconds, nanoseconds = divmod(nanoseconds, 1000)
    if nanoseconds != 0:
        warn(
            "Nanosecond resolution is not available on this platform, value is truncated at microsecond resolution"
        )
    seconds, microseconds = divmod(microseconds, 1000000)
    minutes, seconds = divmod(seconds, 60)
    hours, minutes = divmod(minutes, 60)
    t = time(hours, minutes, seconds, microseconds)
    if tz is None:
        return t
    tz_offset_minutes, tz_offset_seconds = divmod(tz, 60)
    zone = FixedOffset(tz_offset_minutes)
    return zone.localize(t)
예제 #9
0
def hydrate_datetime(seconds, nanoseconds, tz=None):
    """ Hydrator for `DateTime` and `LocalDateTime` values.

    :param seconds:
    :param nanoseconds:
    :param tz:
    :return: datetime
    """
    from pytz import FixedOffset, timezone
    minutes, seconds = map(int, divmod(seconds, 60))
    hours, minutes = map(int, divmod(minutes, 60))
    days, hours = map(int, divmod(hours, 24))
    seconds = (1000000000 * seconds + nanoseconds) / 1000000000
    t = DateTime.combine(Date.from_ordinal(get_date_unix_epoch_ordinal() + days), Time(hours, minutes, seconds))
    if tz is None:
        return t
    if isinstance(tz, int):
        tz_offset_minutes, tz_offset_seconds = divmod(tz, 60)
        zone = FixedOffset(tz_offset_minutes)
    else:
        zone = timezone(tz)
    return zone.localize(t)