Source code for ultipa.utils.ultipa_datetime

import datetime
import re
import time
from dateutil.parser import parse
from ultipa.utils import errors
from ultipa.utils.errors import ParameterException


[docs] class UTC(datetime.tzinfo): def __init__(self, offsetHours=0, offsetSeconds=0): if offsetSeconds is None: self.__offset = 0 else: self.__offset = offsetSeconds self.__offsetHour = offsetHours
[docs] def utcoffset(self, dt): return datetime.timedelta(seconds=self.__offset, hours=self.__offsetHour)
[docs] def tzname(self, dt): return 'UTC+%s dt: %s' % (self.__offsetHour, [dt, id(dt)])
[docs] def dst(self, dt): return datetime.timedelta(seconds=self.__offset, hours=self.__offsetHour)
[docs] def getTimeZoneSeconds(timeZone): import pytz try: tz = pytz.timezone(timeZone) utc_offset = tz.utcoffset(datetime.datetime.utcnow()) return utc_offset.total_seconds() except pytz.exceptions.UnknownTimeZoneError as e: raise errors.ParameterException("UnknownTimeZoneError:" + str(e))
[docs] def getTimeOffsetSeconds(timeZoneOffset): if timeZoneOffset is None: return timeZoneOffset if isinstance(timeZoneOffset, int): return timeZoneOffset elif isinstance(timeZoneOffset, float): return timeZoneOffset elif isinstance(timeZoneOffset, str): pattern = re.compile(r"([+-])(\d{2})(\d{2})") match = pattern.match(timeZoneOffset) if match: sign = match.group(1) hours = int(match.group(2)) minutes = int(match.group(3)) total_offset_minutes = (hours * 60 + minutes) * (-1 if sign == '-' else 1) offset = datetime.timedelta(minutes=total_offset_minutes) return offset.total_seconds() else: raise errors.ParameterException("UnknownTimeZoneOffsetError:" + str(timeZoneOffset)) else: raise errors.ParameterException("UnknownTimeZoneOffsetError:" + str(timeZoneOffset))
[docs] class UltipaDatetime: ''' Processing class for date and time related operations. ''' year = 0 month = 0 day = 0 hour = 0 minute = 0 second = 0 microsecond = 0
[docs] @classmethod def datetimeStr2datetimeInt(self, strDatetime: datetime.datetime): ''' Convert a datatime string into a customized datatime integer. Args: strDatetime: Returns: ''' if isinstance(strDatetime, str): try: data = datetime.datetime.strptime(strDatetime, "%Y-%m-%d %H:%M:%S.%f%z") except: try: data = datetime.datetime.strptime(strDatetime, "%Y-%m-%d %H:%M:%S.%f") except ValueError as e: try: data = datetime.datetime.strptime(strDatetime, "%Y-%m-%d %H:%M:%S") except ValueError as e: try: data = datetime.datetime.strptime(strDatetime, "%Y-%m-%d") except ValueError as e: raise ParameterException(e) elif isinstance(strDatetime, datetime.datetime): data = strDatetime else: raise ParameterException('strDatetime must str %Y-%m-%d %H:%M:%S.%f or datetime type') self.year = data.year self.month = data.month self.day = data.day self.hour = data.hour self.minute = data.minute self.second = data.second self.microsecond = data.microsecond if self.year >= 70 and self.year < 100: self.year += 1900 elif self.year < 70: self.year += 2000 datetime_int = 0 year_month = self.year * 13 + self.month datetime_int |= (year_month << 46) datetime_int |= (self.day << 41) datetime_int |= (self.hour << 36) datetime_int |= (self.minute << 30) datetime_int |= (self.second << 24) datetime_int |= self.microsecond return datetime_int
[docs] @classmethod def timestampStr2timestampInt(self, strDatetime: str, timeZone, timeZoneOffset=0): ''' Convert strings of datetime, timezone and timezone-offset into the Unix timestamp integer in seconds. Args: strDatetime: timeZone: timeZoneOffset: Returns: ''' try: tzinfo = None dt = parse(strDatetime) if dt.utcoffset() is not None: offset_hours = int(dt.utcoffset().total_seconds() / 3600) tzinfo = UTC(offset_hours, timeZoneOffset) if timeZone is not None: total_seconds = getTimeZoneSeconds(timeZone) tzinfo = UTC(0, total_seconds) else: if timeZoneOffset is not None: total_seconds = getTimeOffsetSeconds(timeZoneOffset) tzinfo = UTC(0, total_seconds) timestamp = datetime.datetime(year=dt.year, month=dt.month, day=dt.day, hour=dt.hour, minute=dt.minute, second=dt.second, tzinfo=tzinfo) return int(timestamp.timestamp()) except ValueError as e: raise ParameterException(e)
[docs] @staticmethod def datetimeInt2datetimeStr(datetime_int): ''' Convert the customized datetime integer into a datetime string Args: datetime_int: Returns: ''' if datetime_int < 0: return "" from datetime import datetime year_month = ((datetime_int >> 46) & 0x1FFFF) year = year_month // 13 month = year_month % 13 day = ((datetime_int >> 41) & 0x1F) hour = ((datetime_int >> 36) & 0x1F) minute = ((datetime_int >> 30) & 0x3F) second = ((datetime_int >> 24) & 0x3F) microsecond = (datetime_int & 0xFFFFFF) def pixString(s, length): s = "000000" + str(s) return s[len(s) - length:] if year == 0: return f"{pixString(year, 4)}-{pixString(month, 2)}-{pixString(day, 2)} {pixString(hour, 2)}:{pixString(minute, 2)}:{pixString(second, 2)}.{pixString(microsecond, 2)}" if microsecond == 000000: ret = datetime(year, month, day, hour, minute, second) ret = ret.strftime("%Y-%m-%d %H:%M:%S") else: ret = datetime(year, month, day, hour, minute, second, microsecond) ret = ret.strftime("%Y-%m-%d %H:%M:%S.%f") return ret
[docs] @staticmethod def timestampInt2timestampStr(datetime_int, timeZone: str = None, timeZoneOffset: int = 0): timeStamp = float(datetime_int) offset_hours = 0 if timeZone: total_seconds = getTimeZoneSeconds(timeZone) offset_hours = int(total_seconds / 3600) if timeZoneOffset is None: timeZoneOffset = 0 otherStyleTime = datetime.datetime.fromtimestamp(timeStamp, tz=UTC(offset_hours, timeZoneOffset)) return str(otherStyleTime)
[docs] def wrapper(func): ''' Measures the execution time of a method. Args: func: Returns: ''' def inner(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) end_time = time.time() result = end_time - start_time print('func %s time is: %.3fs' % (func.__name__, result)) return res return inner
[docs] class DateTimestamp(object): """ A class that realizes the mutual conversion of datetime and timestamp. """ def __init__(self, date=None): if date is None: self.timestamp = int(time.time()) self.datetime = self._toDatetime(self.timestamp) else: ### Judge whether the input date is a timestamp ### if isinstance(date, int): self.timestamp = date self.datetime = self._toDatetime(date) else: self.timestamp = self._toTimestamp(date) self.datetime = date if self.timestamp == False: self.year = self.month = self.day = self.hour = self.minute = self.second = False else: self._localtime = time.localtime(self.timestamp) # Parse the tuples from the timestamp self.year = self._localtime.tm_year # Assign year tuple self.month = self._localtime.tm_mon # Assign month tuple self.day = self._localtime.tm_mday # Assign day tuple self.hour = self._localtime.tm_hour # Assign hour tuple self.minute = self._localtime.tm_min # Assign minute tuple self.second = self._localtime.tm_sec # Assign second tuple def _toDatetime(self, timestamp): """ Convert timestamp to datetime """ try: timeStamp = float(timestamp) timeArray = time.localtime(timeStamp) return time.strftime("%Y-%m-%d %H:%M:%S", timeArray) except: return False def _toTimestamp(self, datetimeString): """ Convert datetime to timestamp """ try: return int(time.mktime(time.strptime(datetimeString, "%Y-%m-%d %H:%M:%S"))) except: return False def __str__(self): return self.datetime
[docs] def getTimeZoneOffset(requestConfig, defaultConfig): ''' Get timezone offset Args: requestConfig: defaultConfig: Returns: ''' timeZone = requestConfig.timeZone if requestConfig.timeZone else defaultConfig.timeZone if timeZone is not None: return getTimeZoneSeconds(timeZone) timeZoneOffset = requestConfig.timeZoneOffset if requestConfig.timeZoneOffset else defaultConfig.timeZoneOffset return getTimeOffsetSeconds(timeZoneOffset)