mirror of
https://github.com/marcus-alicia/iRedAdmin-Pro-SQL.git
synced 2026-05-26 15:13:38 +00:00
201 lines
4.6 KiB
Python
201 lines
4.6 KiB
Python
import time
|
|
import re
|
|
from datetime import tzinfo, timedelta, datetime
|
|
|
|
from libs.l10n import TIMEZONE_OFFSETS
|
|
import settings
|
|
|
|
__timezone__ = None
|
|
__local_timezone__ = None
|
|
__timezones__ = {}
|
|
|
|
DEFAULT_DATETIME_INPUT_FORMATS = (
|
|
"%Y-%m-%d %H:%M:%S", # '2006-10-25 14:30:59'
|
|
"%Y-%m-%d %H:%M", # '2006-10-25 14:30'
|
|
"%Y-%m-%d", # '2006-10-25'
|
|
"%Y/%m/%d %H:%M:%S", # '2006/10/25 14:30:59'
|
|
"%Y/%m/%d %H:%M", # '2006/10/25 14:30'
|
|
"%Y/%m/%d ", # '2006/10/25 '
|
|
"%m/%d/%Y %H:%M:%S", # '10/25/2006 14:30:59'
|
|
"%m/%d/%Y %H:%M", # '10/25/2006 14:30'
|
|
"%m/%d/%Y", # '10/25/2006'
|
|
"%m/%d/%y %H:%M:%S", # '10/25/06 14:30:59'
|
|
"%m/%d/%y %H:%M", # '10/25/06 14:30'
|
|
"%m/%d/%y", # '10/25/06'
|
|
"%H:%M:%S", # '14:30:59'
|
|
"%H:%M", # '14:30'
|
|
)
|
|
|
|
ZERO = timedelta(0)
|
|
|
|
|
|
class UTCTimeZone(tzinfo):
|
|
"""UTC"""
|
|
|
|
def utcoffset(self, dt):
|
|
return ZERO
|
|
|
|
def tzname(self, dt):
|
|
return "UTC"
|
|
|
|
def dst(self, dt):
|
|
return ZERO
|
|
|
|
def __repr__(self):
|
|
return "<tzinfo UTC>"
|
|
|
|
|
|
UTC = UTCTimeZone()
|
|
|
|
|
|
class FixedOffset(tzinfo):
|
|
"""Fixed offset in minutes east from UTC."""
|
|
|
|
def __init__(self, offset, name):
|
|
self.__offset = timedelta(minutes=offset)
|
|
self.__name = name
|
|
|
|
def utcoffset(self, dt):
|
|
return self.__offset
|
|
|
|
def tzname(self, dt):
|
|
return self.__name
|
|
|
|
def dst(self, dt):
|
|
return ZERO
|
|
|
|
|
|
for (tzname, offset) in list(TIMEZONE_OFFSETS.items()):
|
|
__timezones__[tzname] = FixedOffset(offset, tzname)
|
|
|
|
re_timezone = re.compile(r"GMT\s?([+-]?)(\d+):(\d\d)", re.IGNORECASE)
|
|
|
|
|
|
def fix_gmt_timezone(tz):
|
|
if isinstance(tz, str):
|
|
b = re_timezone.match(tz)
|
|
if b:
|
|
sign = b.group(1)
|
|
if not sign:
|
|
sign = "+"
|
|
|
|
hour = b.group(2)
|
|
if hour in ["0", "00"]:
|
|
return "UTC"
|
|
|
|
minute = b.group(3)
|
|
return "GMT" + sign + hour + ":" + minute
|
|
return tz
|
|
|
|
|
|
def set_local_timezone(tz):
|
|
global __local_timezone__
|
|
__local_timezone__ = timezone(tz)
|
|
|
|
|
|
def get_local_timezone():
|
|
return __local_timezone__
|
|
|
|
|
|
def timezone(tzname):
|
|
# Validate tzname and return it
|
|
if not tzname:
|
|
return None
|
|
|
|
if isinstance(tzname, str):
|
|
# not pytz module imported, so just return None
|
|
tzname = fix_gmt_timezone(tzname)
|
|
tz = __timezones__.get(tzname, None)
|
|
if not tz:
|
|
tz = UTC
|
|
return tz
|
|
elif isinstance(tzname, tzinfo):
|
|
return tzname
|
|
else:
|
|
return UTC
|
|
|
|
|
|
def pick_timezone(*args):
|
|
for x in args:
|
|
tz = timezone(x)
|
|
if tz:
|
|
return tz
|
|
|
|
|
|
def to_timezone(dt, tzinfo=None):
|
|
"""
|
|
Convert a datetime to timezone
|
|
"""
|
|
if not dt:
|
|
return dt
|
|
tz = pick_timezone(tzinfo, __timezone__)
|
|
if not tz:
|
|
return dt
|
|
dttz = getattr(dt, "tzinfo", None)
|
|
if not dttz:
|
|
return dt.replace(tzinfo=tz)
|
|
else:
|
|
return dt.astimezone(tz)
|
|
|
|
|
|
def to_datetime_with_tzinfo(dt, tzinfo=None, formatstr=None):
|
|
"""
|
|
Convert a date or time to datetime with tzinfo
|
|
"""
|
|
if not dt:
|
|
return dt
|
|
|
|
tz = pick_timezone(tzinfo, __timezone__)
|
|
|
|
if isinstance(dt, str):
|
|
if not formatstr:
|
|
formats = DEFAULT_DATETIME_INPUT_FORMATS
|
|
else:
|
|
formats = list(formatstr)
|
|
d = None
|
|
for fmt in formats:
|
|
try:
|
|
d = datetime(*time.strptime(dt, fmt)[:6])
|
|
except ValueError:
|
|
continue
|
|
if not d:
|
|
return None
|
|
d = d.replace(tzinfo=tz)
|
|
else:
|
|
d = datetime(
|
|
getattr(dt, "year", 1970),
|
|
getattr(dt, "month", 1),
|
|
getattr(dt, "day", 1),
|
|
getattr(dt, "hour", 0),
|
|
getattr(dt, "minute", 0),
|
|
getattr(dt, "second", 0),
|
|
getattr(dt, "microsecond", 0),
|
|
)
|
|
|
|
if not getattr(dt, "tzinfo", None):
|
|
d = d.replace(tzinfo=tz)
|
|
else:
|
|
d = d.replace(tzinfo=dt.tzinfo)
|
|
return to_timezone(d, tzinfo)
|
|
|
|
|
|
def utc_to_timezone(dt, timezone=None, format="%Y-%m-%d %H:%M:%S"):
|
|
if not timezone:
|
|
timezone = settings.LOCAL_TIMEZONE
|
|
|
|
# Convert original timestamp to new timestamp with UTC timezone.
|
|
t = to_datetime_with_tzinfo(dt, tzinfo=UTC)
|
|
|
|
# Convert original timestamp (with UTC timezone) to timestamp with
|
|
# local timezone.
|
|
ft = to_datetime_with_tzinfo(t, tzinfo=timezone)
|
|
|
|
if ft:
|
|
# Check 'daylight saving time'
|
|
if time.localtime().tm_isdst:
|
|
ft += timedelta(seconds=3600)
|
|
|
|
return ft.strftime(format)
|
|
else:
|
|
return "--"
|