def replace(self, hour=None, minute=None, second=None, microsecond=None,
tzinfo=True, *, fold=None):
"""Return a new time with new values for the specified fields."""
microsecond = self.microsecond
return type(self)(hour, minute, second, microsecond, tzinfo, fold=fold)
def _getstate(self, protocol=3):
us2, us3 = divmod(self._microsecond, 256)
us1, us2 = divmod(us2, 256)
if self._fold and protocol > 3:
basestate = bytes([h, self._minute, self._second,
return (basestate, self._tzinfo)
def __setstate(self, string, tzinfo):
if tzinfo is not None and not isinstance(tzinfo, _tzinfo_class):
raise TypeError("bad tzinfo state arg")
h, self._minute, self._second, us1, us2, us3 = string
self._microsecond = (((us1 << 8) | us2) << 8) | us3
def __reduce_ex__(self, protocol):
return (self.__class__, self._getstate(protocol))
return self.__reduce_ex__(2)
_time_class = time # so functions w/ args named "time" can get at the class
time.max = time(23, 59, 59, 999999)
time.resolution = timedelta(microseconds=1)
"""datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])
The year, month and day arguments are required. tzinfo may be None, or an
instance of a tzinfo subclass. The remaining arguments may be ints.
__slots__ = date.__slots__ + time.__slots__
def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0,
microsecond=0, tzinfo=None, *, fold=0):
if (isinstance(year, (bytes, str)) and len(year) == 10 and
1 <= ord(year[2:3])&0x7F <= 12):
if isinstance(year, str):
year = bytes(year, 'latin1')
except UnicodeEncodeError:
# More informative error message.
"Failed to encode latin1 string when unpickling "
"pickle.load(data, encoding='latin1') is assumed.")
self = object.__new__(cls)
self.__setstate(year, month)
year, month, day = _check_date_fields(year, month, day)
hour, minute, second, microsecond, fold = _check_time_fields(
hour, minute, second, microsecond, fold)
_check_tzinfo_arg(tzinfo)
self = object.__new__(cls)
self._microsecond = microsecond
# Read-only field accessors
"""microsecond (0-999999)"""
"""timezone info object"""
def _fromtimestamp(cls, t, utc, tz):
"""Construct a datetime from a POSIX timestamp (like time.time()).
A timezone info object may be passed in as well.
converter = _time.gmtime if utc else _time.localtime
y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
ss = min(ss, 59) # clamp out leap seconds if the platform has them
result = cls(y, m, d, hh, mm, ss, us, tz)
# As of version 2015f max fold in IANA database is
# 23 hours at 1969-09-30 13:00:00 in Kwajalein.
# Let's probe 24 hours in the past to detect a transition:
max_fold_seconds = 24 * 3600
# On Windows localtime_s throws an OSError for negative values,
# thus we can't perform fold detection for values of time less
# than the max time fold. See comments in _datetimemodule's
# version of this method for more details.
if t < max_fold_seconds and sys.platform.startswith("win"):
y, m, d, hh, mm, ss = converter(t - max_fold_seconds)[:6]
probe1 = cls(y, m, d, hh, mm, ss, us, tz)
trans = result - probe1 - timedelta(0, max_fold_seconds)
y, m, d, hh, mm, ss = converter(t + trans // timedelta(0, 1))[:6]
probe2 = cls(y, m, d, hh, mm, ss, us, tz)
result = tz.fromutc(result)
def fromtimestamp(cls, t, tz=None):
"""Construct a datetime from a POSIX timestamp (like time.time()).
A timezone info object may be passed in as well.
return cls._fromtimestamp(t, tz is not None, tz)
def utcfromtimestamp(cls, t):
"""Construct a naive UTC datetime from a POSIX timestamp."""
return cls._fromtimestamp(t, True, None)
"Construct a datetime from time.time() and optional time zone info."
return cls.fromtimestamp(t, tz)
"Construct a UTC datetime from time.time()."
return cls.utcfromtimestamp(t)
def combine(cls, date, time, tzinfo=True):
"Construct a datetime from a given date and a given time."
if not isinstance(date, _date_class):
raise TypeError("date argument must be a date instance")
if not isinstance(time, _time_class):
raise TypeError("time argument must be a time instance")
return cls(date.year, date.month, date.day,
time.hour, time.minute, time.second, time.microsecond,
def fromisoformat(cls, date_string):
"""Construct a datetime from the output of datetime.isoformat()."""
if not isinstance(date_string, str):
raise TypeError('fromisoformat: argument must be str')
# Split this at the separator
date_components = _parse_isoformat_date(dstr)
raise ValueError(f'Invalid isoformat string: {date_string!r}')
time_components = _parse_isoformat_time(tstr)
raise ValueError(f'Invalid isoformat string: {date_string!r}')
time_components = [0, 0, 0, 0, None]
return cls(*(date_components + time_components))
"Return local time tuple compatible with time.localtime()."
return _build_struct_time(self.year, self.month, self.day,
self.hour, self.minute, self.second,
"""Return integer POSIX timestamp."""
epoch = datetime(1970, 1, 1)
max_fold_seconds = 24 * 3600
t = (self - epoch) // timedelta(0, 1)
y, m, d, hh, mm, ss = _time.localtime(u)[:6]
return (datetime(y, m, d, hh, mm, ss) - epoch) // timedelta(0, 1)
# Our goal is to solve t = local(u) for u.
# We found one solution, but it may not be the one we need.
# Look for an earlier solution (if `fold` is 0), or a
# later one (if `fold` is 1).
u2 = u1 + (-max_fold_seconds, max_fold_seconds)[self.fold]
# We have found both offsets a and b, but neither t - a nor t - b is
# a solution. This means t is in the gap.
return (max, min)[self.fold](u1, u2)
"Return POSIX timestamp as float"
return s + self.microsecond / 1e6
return (self - _EPOCH).total_seconds()
"Return UTC time tuple compatible with time.gmtime()."
offset = self.utcoffset()
y, m, d = self.year, self.month, self.day
hh, mm, ss = self.hour, self.minute, self.second
return _build_struct_time(y, m, d, hh, mm, ss, 0)
return date(self._year, self._month, self._day)
"Return the time part, with tzinfo None."
return time(self.hour, self.minute, self.second, self.microsecond, fold=self.fold)
"Return the time part, with same tzinfo."
return time(self.hour, self.minute, self.second, self.microsecond,
self._tzinfo, fold=self.fold)
def replace(self, year=None, month=None, day=None, hour=None,
minute=None, second=None, microsecond=None, tzinfo=True,
"""Return a new datetime with new values for the specified fields."""
microsecond = self.microsecond
return type(self)(year, month, day, hour, minute, second,
microsecond, tzinfo, fold=fold)
def _local_timezone(self):
ts = (self - _EPOCH) // timedelta(seconds=1)
localtm = _time.localtime(ts)
local = datetime(*localtm[:6])
gmtoff = localtm.tm_gmtoff
return timezone(timedelta(seconds=gmtoff), zone)
def astimezone(self, tz=None):
tz = self._local_timezone()
elif not isinstance(tz, tzinfo):
raise TypeError("tz argument must be an instance of tzinfo")
mytz = self._local_timezone()
myoffset = mytz.utcoffset(self)
myoffset = mytz.utcoffset(self)
mytz = self.replace(tzinfo=None)._local_timezone()
myoffset = mytz.utcoffset(self)
# Convert self to UTC, and attach the new time zone object.
utc = (self - myoffset).replace(tzinfo=tz)
# Convert from UTC to tz's local time.
# Ways to produce a string.
"Return ctime() style string."
weekday = self.toordinal() % 7 or 7
return "%s %s %2d %02d:%02d:%02d %04d" % (
_MONTHNAMES[self._month],
self._hour, self._minute, self._second,
def isoformat(self, sep='T', timespec='auto'):
"""Return the time formatted according to ISO.
The full format looks like 'YYYY-MM-DD HH:MM:SS.mmmmmm'.
By default, the fractional part is omitted if self.microsecond == 0.
If self.tzinfo is not None, the UTC offset is also attached, giving
giving a full format of 'YYYY-MM-DD HH:MM:SS.mmmmmm+HH:MM'.
Optional argument sep specifies the separator between date and
The optional argument timespec specifies the number of additional
terms of the time to include. Valid options are 'auto', 'hours',
'minutes', 'seconds', 'milliseconds' and 'microseconds'.
s = ("%04d-%02d-%02d%c" % (self._year, self._month, self._day, sep) +
_format_time(self._hour, self._minute, self._second,
self._microsecond, timespec))
"""Convert to formal string, for repr()."""
L = [self._year, self._month, self._day, # These are never zero
self._hour, self._minute, self._second, self._microsecond]
s = "%s.%s(%s)" % (self.__class__.__module__,
self.__class__.__qualname__,
if self._tzinfo is not None:
s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
"Convert to string, for str()."
return self.isoformat(sep=' ')
def strptime(cls, date_string, format):
'string, format -> new datetime parsed from a string (like time.strptime()).'
return _strptime._strptime_datetime(cls, date_string, format)
"""Return the timezone offset as timedelta positive east of UTC (negative west of
offset = self._tzinfo.utcoffset(self)
_check_utc_offset("utcoffset", offset)
"""Return the timezone name.
Note that the name is 100% informational -- there's no requirement that
it mean anything in particular. For example, "GMT", "UTC", "-500",
"-5:00", "EDT", "US/Eastern", "America/New York" are all valid replies.
name = self._tzinfo.tzname(self)
"""Return 0 if DST is not in effect, or the DST offset (as timedelta
positive eastward) if DST is in effect.
This is purely informational; the DST offset has already been added to
the UTC offset returned by utcoffset() if applicable, so there's no
need to consult dst() unless you're interested in displaying the DST
offset = self._tzinfo.dst(self)
_check_utc_offset("dst", offset)
# Comparisons of datetime objects with other.
if isinstance(other, datetime):
return self._cmp(other, allow_mixed=True) == 0
elif not isinstance(other, date):
if isinstance(other, datetime):
return self._cmp(other) <= 0
elif not isinstance(other, date):