kopia lustrzana https://github.com/micropython/micropython-lib
880 wiersze
21 KiB
Python
880 wiersze
21 KiB
Python
# datetime.py
|
|
|
|
import time as _tmod
|
|
|
|
__version__ = "2.0.0"
|
|
|
|
_DBM = (0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334)
|
|
_DIM = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
|
|
_TIME_SPEC = ("auto", "hours", "minutes", "seconds", "milliseconds", "microseconds")
|
|
|
|
|
|
def _leap(y):
|
|
return y % 4 == 0 and (y % 100 != 0 or y % 400 == 0)
|
|
|
|
|
|
def _dby(y):
|
|
# year -> number of days before January 1st of year.
|
|
Y = y - 1
|
|
return Y * 365 + Y // 4 - Y // 100 + Y // 400
|
|
|
|
|
|
def _dim(y, m):
|
|
# year, month -> number of days in that month in that year.
|
|
if m == 2 and _leap(y):
|
|
return 29
|
|
return _DIM[m]
|
|
|
|
|
|
def _dbm(y, m):
|
|
# year, month -> number of days in year preceding first day of month.
|
|
return _DBM[m] + (m > 2 and _leap(y))
|
|
|
|
|
|
def _ymd2o(y, m, d):
|
|
# y, month, day -> ordinal, considering 01-Jan-0001 as day 1.
|
|
return _dby(y) + _dbm(y, m) + d
|
|
|
|
|
|
def _o2ymd(n):
|
|
# ordinal -> (year, month, day), considering 01-Jan-0001 as day 1.
|
|
n -= 1
|
|
n400, n = divmod(n, 146_097)
|
|
y = n400 * 400 + 1
|
|
n100, n = divmod(n, 36_524)
|
|
n4, n = divmod(n, 1_461)
|
|
n1, n = divmod(n, 365)
|
|
y += n100 * 100 + n4 * 4 + n1
|
|
if n1 == 4 or n100 == 4:
|
|
return y - 1, 12, 31
|
|
m = (n + 50) >> 5
|
|
prec = _dbm(y, m)
|
|
if prec > n:
|
|
m -= 1
|
|
prec -= _dim(y, m)
|
|
n -= prec
|
|
return y, m, n + 1
|
|
|
|
|
|
MINYEAR = 1
|
|
MAXYEAR = 9_999
|
|
|
|
|
|
class timedelta:
|
|
def __init__(
|
|
self, days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0
|
|
):
|
|
s = (((weeks * 7 + days) * 24 + hours) * 60 + minutes) * 60 + seconds
|
|
self._us = round((s * 1000 + milliseconds) * 1000 + microseconds)
|
|
|
|
def __repr__(self):
|
|
return "datetime.timedelta(microseconds={})".format(self._us)
|
|
|
|
def total_seconds(self):
|
|
return self._us / 1_000_000
|
|
|
|
@property
|
|
def days(self):
|
|
return self._tuple(2)[0]
|
|
|
|
@property
|
|
def seconds(self):
|
|
return self._tuple(3)[1]
|
|
|
|
@property
|
|
def microseconds(self):
|
|
return self._tuple(3)[2]
|
|
|
|
def __add__(self, other):
|
|
if isinstance(other, datetime):
|
|
return other.__add__(self)
|
|
else:
|
|
us = other._us
|
|
return timedelta(0, 0, self._us + us)
|
|
|
|
def __sub__(self, other):
|
|
return timedelta(0, 0, self._us - other._us)
|
|
|
|
def __neg__(self):
|
|
return timedelta(0, 0, -self._us)
|
|
|
|
def __pos__(self):
|
|
return self
|
|
|
|
def __abs__(self):
|
|
return -self if self._us < 0 else self
|
|
|
|
def __mul__(self, other):
|
|
return timedelta(0, 0, round(other * self._us))
|
|
|
|
__rmul__ = __mul__
|
|
|
|
def __truediv__(self, other):
|
|
if isinstance(other, timedelta):
|
|
return self._us / other._us
|
|
else:
|
|
return timedelta(0, 0, round(self._us / other))
|
|
|
|
def __floordiv__(self, other):
|
|
if isinstance(other, timedelta):
|
|
return self._us // other._us
|
|
else:
|
|
return timedelta(0, 0, int(self._us // other))
|
|
|
|
def __mod__(self, other):
|
|
return timedelta(0, 0, self._us % other._us)
|
|
|
|
def __divmod__(self, other):
|
|
q, r = divmod(self._us, other._us)
|
|
return q, timedelta(0, 0, r)
|
|
|
|
def __eq__(self, other):
|
|
return self._us == other._us
|
|
|
|
def __le__(self, other):
|
|
return self._us <= other._us
|
|
|
|
def __lt__(self, other):
|
|
return self._us < other._us
|
|
|
|
def __ge__(self, other):
|
|
return self._us >= other._us
|
|
|
|
def __gt__(self, other):
|
|
return self._us > other._us
|
|
|
|
def __bool__(self):
|
|
return self._us != 0
|
|
|
|
def __str__(self):
|
|
return self._format(0x40)
|
|
|
|
def __hash__(self):
|
|
if not hasattr(self, "_hash"):
|
|
self._hash = hash(self._us)
|
|
return self._hash
|
|
|
|
def isoformat(self):
|
|
return self._format(0)
|
|
|
|
def _format(self, spec=0):
|
|
if self._us >= 0:
|
|
td = self
|
|
g = ""
|
|
else:
|
|
td = -self
|
|
g = "-"
|
|
d, h, m, s, us = td._tuple(5)
|
|
ms, us = divmod(us, 1000)
|
|
r = ""
|
|
if spec & 0x40:
|
|
spec &= ~0x40
|
|
hr = str(h)
|
|
else:
|
|
hr = f"{h:02d}"
|
|
if spec & 0x20:
|
|
spec &= ~0x20
|
|
spec |= 0x10
|
|
r += "UTC"
|
|
if spec & 0x10:
|
|
spec &= ~0x10
|
|
if not g:
|
|
g = "+"
|
|
if d:
|
|
p = "s" if d > 1 else ""
|
|
r += f"{g}{d} day{p}, "
|
|
g = ""
|
|
if spec == 0:
|
|
spec = 5 if (ms or us) else 3
|
|
if spec >= 1 or h:
|
|
r += f"{g}{hr}"
|
|
if spec >= 2 or m:
|
|
r += f":{m:02d}"
|
|
if spec >= 3 or s:
|
|
r += f":{s:02d}"
|
|
if spec >= 4 or ms:
|
|
r += f".{ms:03d}"
|
|
if spec >= 5 or us:
|
|
r += f"{us:03d}"
|
|
return r
|
|
|
|
def tuple(self):
|
|
return self._tuple(5)
|
|
|
|
def _tuple(self, n):
|
|
d, us = divmod(self._us, 86_400_000_000)
|
|
if n == 2:
|
|
return d, us
|
|
s, us = divmod(us, 1_000_000)
|
|
if n == 3:
|
|
return d, s, us
|
|
h, s = divmod(s, 3600)
|
|
m, s = divmod(s, 60)
|
|
return d, h, m, s, us
|
|
|
|
|
|
timedelta.min = timedelta(days=-999_999_999)
|
|
timedelta.max = timedelta(days=999_999_999, hours=23, minutes=59, seconds=59, microseconds=999_999)
|
|
timedelta.resolution = timedelta(microseconds=1)
|
|
|
|
|
|
class tzinfo:
|
|
# abstract class
|
|
def tzname(self, dt):
|
|
raise NotImplementedError
|
|
|
|
def utcoffset(self, dt):
|
|
raise NotImplementedError
|
|
|
|
def dst(self, dt):
|
|
raise NotImplementedError
|
|
|
|
def fromutc(self, dt):
|
|
if dt._tz is not self:
|
|
raise ValueError
|
|
|
|
# See original datetime.py for an explanation of this algorithm.
|
|
dtoff = dt.utcoffset()
|
|
dtdst = dt.dst()
|
|
delta = dtoff - dtdst
|
|
if delta:
|
|
dt += delta
|
|
dtdst = dt.dst()
|
|
return dt + dtdst
|
|
|
|
def isoformat(self, dt):
|
|
return self.utcoffset(dt)._format(0x12)
|
|
|
|
|
|
class timezone(tzinfo):
|
|
def __init__(self, offset, name=None):
|
|
if not (abs(offset._us) < 86_400_000_000):
|
|
raise ValueError
|
|
self._offset = offset
|
|
self._name = name
|
|
|
|
def __repr__(self):
|
|
return "datetime.timezone({}, {})".format(repr(self._offset), repr(self._name))
|
|
|
|
def __eq__(self, other):
|
|
if isinstance(other, timezone):
|
|
return self._offset == other._offset
|
|
return NotImplemented
|
|
|
|
def __str__(self):
|
|
return self.tzname(None)
|
|
|
|
def __hash__(self):
|
|
if not hasattr(self, "_hash"):
|
|
self._hash = hash((self._offset, self._name))
|
|
return self._hash
|
|
|
|
def utcoffset(self, dt):
|
|
return self._offset
|
|
|
|
def dst(self, dt):
|
|
return None
|
|
|
|
def tzname(self, dt):
|
|
if self._name:
|
|
return self._name
|
|
return self._offset._format(0x22)
|
|
|
|
def fromutc(self, dt):
|
|
return dt + self._offset
|
|
|
|
|
|
timezone.utc = timezone(timedelta(0))
|
|
|
|
|
|
def _date(y, m, d):
|
|
if MINYEAR <= y <= MAXYEAR and 1 <= m <= 12 and 1 <= d <= _dim(y, m):
|
|
return _ymd2o(y, m, d)
|
|
elif y == 0 and m == 0 and 1 <= d <= 3_652_059:
|
|
return d
|
|
else:
|
|
raise ValueError
|
|
|
|
|
|
def _iso2d(s): # ISO -> date
|
|
if len(s) < 10 or s[4] != "-" or s[7] != "-":
|
|
raise ValueError
|
|
return int(s[0:4]), int(s[5:7]), int(s[8:10])
|
|
|
|
|
|
def _d2iso(o): # date -> ISO
|
|
return "%04d-%02d-%02d" % _o2ymd(o)
|
|
|
|
|
|
class date:
|
|
def __init__(self, year, month, day):
|
|
self._ord = _date(year, month, day)
|
|
|
|
@classmethod
|
|
def fromtimestamp(cls, ts):
|
|
return cls(*_tmod.localtime(ts)[:3])
|
|
|
|
@classmethod
|
|
def today(cls):
|
|
return cls(*_tmod.localtime()[:3])
|
|
|
|
@classmethod
|
|
def fromordinal(cls, n):
|
|
return cls(0, 0, n)
|
|
|
|
@classmethod
|
|
def fromisoformat(cls, s):
|
|
return cls(*_iso2d(s))
|
|
|
|
@property
|
|
def year(self):
|
|
return self.tuple()[0]
|
|
|
|
@property
|
|
def month(self):
|
|
return self.tuple()[1]
|
|
|
|
@property
|
|
def day(self):
|
|
return self.tuple()[2]
|
|
|
|
def toordinal(self):
|
|
return self._ord
|
|
|
|
def timetuple(self):
|
|
y, m, d = self.tuple()
|
|
yday = _dbm(y, m) + d
|
|
return (y, m, d, 0, 0, 0, self.weekday(), yday, -1)
|
|
|
|
def replace(self, year=None, month=None, day=None):
|
|
year_, month_, day_ = self.tuple()
|
|
if year is None:
|
|
year = year_
|
|
if month is None:
|
|
month = month_
|
|
if day is None:
|
|
day = day_
|
|
return date(year, month, day)
|
|
|
|
def __add__(self, other):
|
|
return date.fromordinal(self._ord + other.days)
|
|
|
|
def __sub__(self, other):
|
|
if isinstance(other, date):
|
|
return timedelta(days=self._ord - other._ord)
|
|
else:
|
|
return date.fromordinal(self._ord - other.days)
|
|
|
|
def __eq__(self, other):
|
|
if isinstance(other, date):
|
|
return self._ord == other._ord
|
|
else:
|
|
return False
|
|
|
|
def __le__(self, other):
|
|
return self._ord <= other._ord
|
|
|
|
def __lt__(self, other):
|
|
return self._ord < other._ord
|
|
|
|
def __ge__(self, other):
|
|
return self._ord >= other._ord
|
|
|
|
def __gt__(self, other):
|
|
return self._ord > other._ord
|
|
|
|
def weekday(self):
|
|
return (self._ord + 6) % 7
|
|
|
|
def isoweekday(self):
|
|
return self._ord % 7 or 7
|
|
|
|
def isoformat(self):
|
|
return _d2iso(self._ord)
|
|
|
|
def __repr__(self):
|
|
return "datetime.date(0, 0, {})".format(self._ord)
|
|
|
|
__str__ = isoformat
|
|
|
|
def __hash__(self):
|
|
if not hasattr(self, "_hash"):
|
|
self._hash = hash(self._ord)
|
|
return self._hash
|
|
|
|
def tuple(self):
|
|
return _o2ymd(self._ord)
|
|
|
|
|
|
date.min = date(MINYEAR, 1, 1)
|
|
date.max = date(MAXYEAR, 12, 31)
|
|
date.resolution = timedelta(days=1)
|
|
|
|
|
|
def _time(h, m, s, us, fold):
|
|
if (
|
|
0 <= h < 24
|
|
and 0 <= m < 60
|
|
and 0 <= s < 60
|
|
and 0 <= us < 1_000_000
|
|
and (fold == 0 or fold == 1)
|
|
) or (h == 0 and m == 0 and s == 0 and 0 < us < 86_400_000_000):
|
|
return timedelta(0, s, us, 0, m, h)
|
|
else:
|
|
raise ValueError
|
|
|
|
|
|
def _iso2t(s):
|
|
hour = 0
|
|
minute = 0
|
|
sec = 0
|
|
usec = 0
|
|
tz_sign = ""
|
|
tz_hour = 0
|
|
tz_minute = 0
|
|
tz_sec = 0
|
|
tz_usec = 0
|
|
l = len(s)
|
|
i = 0
|
|
if l < 2:
|
|
raise ValueError
|
|
i += 2
|
|
hour = int(s[i - 2 : i])
|
|
if l > i and s[i] == ":":
|
|
i += 3
|
|
if l - i < 0:
|
|
raise ValueError
|
|
minute = int(s[i - 2 : i])
|
|
if l > i and s[i] == ":":
|
|
i += 3
|
|
if l - i < 0:
|
|
raise ValueError
|
|
sec = int(s[i - 2 : i])
|
|
if l > i and s[i] == ".":
|
|
i += 4
|
|
if l - i < 0:
|
|
raise ValueError
|
|
usec = 1000 * int(s[i - 3 : i])
|
|
if l > i and s[i] != "+":
|
|
i += 3
|
|
if l - i < 0:
|
|
raise ValueError
|
|
usec += int(s[i - 3 : i])
|
|
if l > i:
|
|
if s[i] not in "+-":
|
|
raise ValueError
|
|
tz_sign = s[i]
|
|
i += 6
|
|
if l - i < 0:
|
|
raise ValueError
|
|
tz_hour = int(s[i - 5 : i - 3])
|
|
tz_minute = int(s[i - 2 : i])
|
|
if l > i and s[i] == ":":
|
|
i += 3
|
|
if l - i < 0:
|
|
raise ValueError
|
|
tz_sec = int(s[i - 2 : i])
|
|
if l > i and s[i] == ".":
|
|
i += 7
|
|
if l - i < 0:
|
|
raise ValueError
|
|
tz_usec = int(s[i - 6 : i])
|
|
if l != i:
|
|
raise ValueError
|
|
if tz_sign:
|
|
td = timedelta(hours=tz_hour, minutes=tz_minute, seconds=tz_sec, microseconds=tz_usec)
|
|
if tz_sign == "-":
|
|
td = -td
|
|
tz = timezone(td)
|
|
else:
|
|
tz = None
|
|
return hour, minute, sec, usec, tz
|
|
|
|
|
|
def _t2iso(td, timespec, dt, tz):
|
|
s = td._format(_TIME_SPEC.index(timespec))
|
|
if tz is not None:
|
|
s += tz.isoformat(dt)
|
|
return s
|
|
|
|
|
|
class time:
|
|
def __init__(self, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0):
|
|
self._td = _time(hour, minute, second, microsecond, fold)
|
|
self._tz = tzinfo
|
|
self._fd = fold
|
|
|
|
@classmethod
|
|
def fromisoformat(cls, s):
|
|
return cls(*_iso2t(s))
|
|
|
|
@property
|
|
def hour(self):
|
|
return self.tuple()[0]
|
|
|
|
@property
|
|
def minute(self):
|
|
return self.tuple()[1]
|
|
|
|
@property
|
|
def second(self):
|
|
return self.tuple()[2]
|
|
|
|
@property
|
|
def microsecond(self):
|
|
return self.tuple()[3]
|
|
|
|
@property
|
|
def tzinfo(self):
|
|
return self._tz
|
|
|
|
@property
|
|
def fold(self):
|
|
return self._fd
|
|
|
|
def replace(
|
|
self, hour=None, minute=None, second=None, microsecond=None, tzinfo=True, *, fold=None
|
|
):
|
|
h, m, s, us, tz, fl = self.tuple()
|
|
if hour is None:
|
|
hour = h
|
|
if minute is None:
|
|
minute = m
|
|
if second is None:
|
|
second = s
|
|
if microsecond is None:
|
|
microsecond = us
|
|
if tzinfo is True:
|
|
tzinfo = tz
|
|
if fold is None:
|
|
fold = fl
|
|
return time(hour, minute, second, microsecond, tzinfo, fold=fold)
|
|
|
|
def isoformat(self, timespec="auto"):
|
|
return _t2iso(self._td, timespec, None, self._tz)
|
|
|
|
def __repr__(self):
|
|
return "datetime.time(microsecond={}, tzinfo={}, fold={})".format(
|
|
self._td._us, repr(self._tz), self._fd
|
|
)
|
|
|
|
__str__ = isoformat
|
|
|
|
def __bool__(self):
|
|
return True
|
|
|
|
def __eq__(self, other):
|
|
if (self._tz == None) ^ (other._tz == None):
|
|
return False
|
|
return self._sub(other) == 0
|
|
|
|
def __le__(self, other):
|
|
return self._sub(other) <= 0
|
|
|
|
def __lt__(self, other):
|
|
return self._sub(other) < 0
|
|
|
|
def __ge__(self, other):
|
|
return self._sub(other) >= 0
|
|
|
|
def __gt__(self, other):
|
|
return self._sub(other) > 0
|
|
|
|
def _sub(self, other):
|
|
tz1 = self._tz
|
|
if (tz1 is None) ^ (other._tz is None):
|
|
raise TypeError
|
|
us1 = self._td._us
|
|
us2 = other._td._us
|
|
if tz1 is not None:
|
|
os1 = self.utcoffset()._us
|
|
os2 = other.utcoffset()._us
|
|
if os1 != os2:
|
|
us1 -= os1
|
|
us2 -= os2
|
|
return us1 - us2
|
|
|
|
def __hash__(self):
|
|
if not hasattr(self, "_hash"):
|
|
# fold doesn't make any difference
|
|
self._hash = hash((self._td, self._tz))
|
|
return self._hash
|
|
|
|
def utcoffset(self):
|
|
return None if self._tz is None else self._tz.utcoffset(None)
|
|
|
|
def dst(self):
|
|
return None if self._tz is None else self._tz.dst(None)
|
|
|
|
def tzname(self):
|
|
return None if self._tz is None else self._tz.tzname(None)
|
|
|
|
def tuple(self):
|
|
d, h, m, s, us = self._td.tuple()
|
|
return h, m, s, us, self._tz, self._fd
|
|
|
|
|
|
time.min = time(0)
|
|
time.max = time(23, 59, 59, 999_999)
|
|
time.resolution = timedelta.resolution
|
|
|
|
|
|
class datetime:
|
|
def __init__(
|
|
self, year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0
|
|
):
|
|
self._d = _date(year, month, day)
|
|
self._t = _time(hour, minute, second, microsecond, fold)
|
|
self._tz = tzinfo
|
|
self._fd = fold
|
|
|
|
@classmethod
|
|
def fromtimestamp(cls, ts, tz=None):
|
|
if isinstance(ts, float):
|
|
ts, us = divmod(round(ts * 1_000_000), 1_000_000)
|
|
else:
|
|
us = 0
|
|
if tz is None:
|
|
raise NotImplementedError
|
|
else:
|
|
dt = cls(*_tmod.gmtime(ts)[:6], microsecond=us, tzinfo=tz)
|
|
dt = tz.fromutc(dt)
|
|
return dt
|
|
|
|
@classmethod
|
|
def now(cls, tz=None):
|
|
return cls.fromtimestamp(_tmod.time(), tz)
|
|
|
|
@classmethod
|
|
def fromordinal(cls, n):
|
|
return cls(0, 0, n)
|
|
|
|
@classmethod
|
|
def fromisoformat(cls, s):
|
|
d = _iso2d(s)
|
|
if len(s) <= 12:
|
|
return cls(*d)
|
|
t = _iso2t(s[11:])
|
|
return cls(*(d + t))
|
|
|
|
@classmethod
|
|
def combine(cls, date, time, tzinfo=None):
|
|
return cls(
|
|
0, 0, date.toordinal(), 0, 0, 0, time._td._us, tzinfo or time._tz, fold=time._fd
|
|
)
|
|
|
|
@property
|
|
def year(self):
|
|
return _o2ymd(self._d)[0]
|
|
|
|
@property
|
|
def month(self):
|
|
return _o2ymd(self._d)[1]
|
|
|
|
@property
|
|
def day(self):
|
|
return _o2ymd(self._d)[2]
|
|
|
|
@property
|
|
def hour(self):
|
|
return self._t.tuple()[1]
|
|
|
|
@property
|
|
def minute(self):
|
|
return self._t.tuple()[2]
|
|
|
|
@property
|
|
def second(self):
|
|
return self._t.tuple()[3]
|
|
|
|
@property
|
|
def microsecond(self):
|
|
return self._t.tuple()[4]
|
|
|
|
@property
|
|
def tzinfo(self):
|
|
return self._tz
|
|
|
|
@property
|
|
def fold(self):
|
|
return self._fd
|
|
|
|
def __add__(self, other):
|
|
us = self._t._us + other._us
|
|
d, us = divmod(us, 86_400_000_000)
|
|
d += self._d
|
|
return datetime(0, 0, d, 0, 0, 0, us, self._tz)
|
|
|
|
def __sub__(self, other):
|
|
if isinstance(other, timedelta):
|
|
return self.__add__(-other)
|
|
elif isinstance(other, datetime):
|
|
d, us = self._sub(other)
|
|
return timedelta(d, 0, us)
|
|
else:
|
|
raise TypeError
|
|
|
|
def _sub(self, other):
|
|
# Subtract two datetime instances.
|
|
tz1 = self._tz
|
|
if (tz1 is None) ^ (other._tz is None):
|
|
raise TypeError
|
|
dt1 = self
|
|
dt2 = other
|
|
if tz1 is not None:
|
|
os1 = dt1.utcoffset()
|
|
os2 = dt2.utcoffset()
|
|
if os1 != os2:
|
|
dt1 -= os1
|
|
dt2 -= os2
|
|
D = dt1._d - dt2._d
|
|
us = dt1._t._us - dt2._t._us
|
|
d, us = divmod(us, 86_400_000_000)
|
|
return D + d, us
|
|
|
|
def __eq__(self, other):
|
|
if (self._tz == None) ^ (other._tz == None):
|
|
return False
|
|
return self._cmp(other) == 0
|
|
|
|
def __le__(self, other):
|
|
return self._cmp(other) <= 0
|
|
|
|
def __lt__(self, other):
|
|
return self._cmp(other) < 0
|
|
|
|
def __ge__(self, other):
|
|
return self._cmp(other) >= 0
|
|
|
|
def __gt__(self, other):
|
|
return self._cmp(other) > 0
|
|
|
|
def _cmp(self, other):
|
|
# Compare two datetime instances.
|
|
d, us = self._sub(other)
|
|
if d < 0:
|
|
return -1
|
|
if d > 0:
|
|
return 1
|
|
|
|
if us < 0:
|
|
return -1
|
|
if us > 0:
|
|
return 1
|
|
|
|
return 0
|
|
|
|
def date(self):
|
|
return date.fromordinal(self._d)
|
|
|
|
def time(self):
|
|
return time(microsecond=self._t._us, fold=self._fd)
|
|
|
|
def timetz(self):
|
|
return time(microsecond=self._t._us, tzinfo=self._tz, fold=self._fd)
|
|
|
|
def replace(
|
|
self,
|
|
year=None,
|
|
month=None,
|
|
day=None,
|
|
hour=None,
|
|
minute=None,
|
|
second=None,
|
|
microsecond=None,
|
|
tzinfo=True,
|
|
*,
|
|
fold=None,
|
|
):
|
|
Y, M, D, h, m, s, us, tz, fl = self.tuple()
|
|
if year is None:
|
|
year = Y
|
|
if month is None:
|
|
month = M
|
|
if day is None:
|
|
day = D
|
|
if hour is None:
|
|
hour = h
|
|
if minute is None:
|
|
minute = m
|
|
if second is None:
|
|
second = s
|
|
if microsecond is None:
|
|
microsecond = us
|
|
if tzinfo is True:
|
|
tzinfo = tz
|
|
if fold is None:
|
|
fold = fl
|
|
return datetime(year, month, day, hour, minute, second, microsecond, tzinfo, fold=fold)
|
|
|
|
def astimezone(self, tz=None):
|
|
if self._tz is tz:
|
|
return self
|
|
_tz = self._tz
|
|
if _tz is None:
|
|
raise NotImplementedError
|
|
else:
|
|
os = _tz.utcoffset(self)
|
|
utc = self - os
|
|
utc = utc.replace(tzinfo=tz)
|
|
return tz.fromutc(utc)
|
|
|
|
def utcoffset(self):
|
|
return None if self._tz is None else self._tz.utcoffset(self)
|
|
|
|
def dst(self):
|
|
return None if self._tz is None else self._tz.dst(self)
|
|
|
|
def tzname(self):
|
|
return None if self._tz is None else self._tz.tzname(self)
|
|
|
|
def timetuple(self):
|
|
if self._tz is None:
|
|
conv = _tmod.gmtime
|
|
epoch = datetime.EPOCH.replace(tzinfo=None)
|
|
else:
|
|
conv = _tmod.localtime
|
|
epoch = datetime.EPOCH
|
|
return conv(round((self - epoch).total_seconds()))
|
|
|
|
def toordinal(self):
|
|
return self._d
|
|
|
|
def timestamp(self):
|
|
if self._tz is None:
|
|
raise NotImplementedError
|
|
else:
|
|
return (self - datetime.EPOCH).total_seconds()
|
|
|
|
def weekday(self):
|
|
return (self._d + 6) % 7
|
|
|
|
def isoweekday(self):
|
|
return self._d % 7 or 7
|
|
|
|
def isoformat(self, sep="T", timespec="auto"):
|
|
return _d2iso(self._d) + sep + _t2iso(self._t, timespec, self, self._tz)
|
|
|
|
def __repr__(self):
|
|
Y, M, D, h, m, s, us, tz, fold = self.tuple()
|
|
tz = repr(tz)
|
|
return "datetime.datetime({}, {}, {}, {}, {}, {}, {}, {}, fold={})".format(
|
|
Y, M, D, h, m, s, us, tz, fold
|
|
)
|
|
|
|
def __str__(self):
|
|
return self.isoformat(" ")
|
|
|
|
def __hash__(self):
|
|
if not hasattr(self, "_hash"):
|
|
self._hash = hash((self._d, self._t, self._tz))
|
|
return self._hash
|
|
|
|
def tuple(self):
|
|
d = _o2ymd(self._d)
|
|
t = self._t.tuple()[1:]
|
|
return d + t + (self._tz, self._fd)
|
|
|
|
|
|
datetime.EPOCH = datetime(*_tmod.gmtime(0)[:6], tzinfo=timezone.utc)
|