diff --git a/src/gam/iso8601.shouldnotbehere/__init__.py b/src/gam/iso8601.shouldnotbehere/__init__.py deleted file mode 100644 index 8654fdf5..00000000 --- a/src/gam/iso8601.shouldnotbehere/__init__.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Copyright (c) 2007 - 2015 Michael Twomey -# -# Permission is hereby granted, free of charge, to any person obtaining a -# copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -"""ISO 8601 date time string parsing - -""" - -__all__ = ["parse_date", "ParseError", "UTC"] diff --git a/src/gam/iso8601.shouldnotbehere/iso8601.py b/src/gam/iso8601.shouldnotbehere/iso8601.py deleted file mode 100644 index 5f8f904a..00000000 --- a/src/gam/iso8601.shouldnotbehere/iso8601.py +++ /dev/null @@ -1,160 +0,0 @@ -# -*- coding: utf-8 -*- -"""ISO 8601 date time string parsing - -""" - -from datetime import (datetime, timedelta, tzinfo) -import time as _time -import re - -ISO8601_REGEX = re.compile(r'^(?P[0-9]{4})-(?P[0-9]{2})-(?P[0-9]{2})(?P[ T])(?P[0-9]{2}):(?P[0-9]{2}):(?P[0-9]{2})([.,](?P[0-9]+)){0,1}(?PZ|(?P[-+])(?P[0-9]{2}):(?P[0-9]{2}))$') -ISO8601_TZ_REGEX = re.compile(r'^(?PZ|(?P[-+])(?P[0-9]{2}):(?P[0-9]{2}))$') - -class ParseError(Exception): - """Raised when there is a problem parsing a date string""" - -# Yoinked from python docs -ZERO = timedelta(0) -class Utc(tzinfo): - """UTC Timezone - - """ - def utcoffset(self, dt): - return ZERO - - def tzname(self, dt): - return "UTC" - - def dst(self, dt): - return ZERO - - def __repr__(self): - return "" - -UTC = Utc() - -class FixedOffset(tzinfo): - """Fixed offset in hours and minutes from UTC - - """ - def __init__(self, offset_hours, offset_minutes, name): - self.__offset_hours = offset_hours # Keep for later __getinitargs__ - self.__offset_minutes = offset_minutes # Keep for later __getinitargs__ - self.__offset = timedelta(hours=offset_hours, minutes=offset_minutes) - self.__name = name - - def __eq__(self, other): - if isinstance(other, FixedOffset): - return (other.__offset == self.__offset) and (other.__name == self.__name) - if isinstance(other, tzinfo): - return other == self - return False - - def __getinitargs__(self): - return (self.__offset_hours, self.__offset_minutes, self.__name) - - def utcoffset(self, dt): - return self.__offset - - def tzname(self, dt): - return self.__name - - def dst(self, dt): - return ZERO - - def __repr__(self): - return "" % (self.__name, self.__offset) - -# A class capturing the platform's idea of local time. - -STDOFFSET = timedelta(seconds = -_time.timezone) -if _time.daylight: - DSTOFFSET = timedelta(seconds = -_time.altzone) -else: - DSTOFFSET = STDOFFSET - -DSTDIFF = DSTOFFSET - STDOFFSET - -class LocalTimezone(tzinfo): - """Local time zone - - """ - - def utcoffset(self, dt): - if self._isdst(dt): - return DSTOFFSET - else: - return STDOFFSET - - def dst(self, dt): - if self._isdst(dt): - return DSTDIFF - else: - return ZERO - - def tzname(self, dt): - return _time.tzname[self._isdst(dt)] - - def _isdst(self, dt): - tt = (dt.year, dt.month, dt.day, - dt.hour, dt.minute, dt.second, - dt.weekday(), 0, 0) - stamp = _time.mktime(tt) - tt = _time.localtime(stamp) - return tt.tm_isdst > 0 - -Local = LocalTimezone() - -def parse_timezone(matches): - """Parses ISO 8601 time zone specs into tzinfo offsets - - """ - - if matches["timezone"] == "Z": - return UTC - sign = matches["tz_sign"] - hours = int(matches['tz_hour']) - minutes = int(matches['tz_minute']) - description = "%s%02d:%02d" % (sign, hours, minutes) - if sign == "-": - hours = -hours - minutes = -minutes - return FixedOffset(hours, minutes, description) - -def parse_timezone_str(tzstring): - m = ISO8601_TZ_REGEX.match(tzstring) - if not m: - raise ParseError("Unable to parse timezone string %r" % tzstring) - groups = m.groupdict() - return parse_timezone(groups) - -def parse_date(datestring): - """Parses ISO 8601 dates into datetime objects - - The timezone is parsed from the date string. However it is quite common to - have dates without a timezone (not strictly correct). In this case the - default timezone specified in default_timezone is used. This is UTC by - default. - - :param datestring: The date to parse as a string - :returns: A datetime.datetime instance - :raises: ParseError when there is a problem parsing the date or - constructing the datetime instance. - - """ - m = ISO8601_REGEX.match(datestring) - if not m: - raise ParseError("Unable to parse date string %r" % datestring) - groups = m.groupdict() - tz = parse_timezone(groups) - try: - return (datetime(year=int(groups['year']), - month=int(groups['month']), - day=int(groups['day']), - hour=int(groups['hour']), - minute=int(groups['minute']), - second=int(groups['second']), - tzinfo=tz), - tz) - except Exception as e: - raise ParseError(e)