Python datetime.replace() Examples
The following are 28
code examples of datetime.replace().
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
You may also want to check out all available functions/classes of the module
datetime
, or try the search function
.
![](https://www.programcreek.com/common/static/images/search.png)
Example #1
Source File: dates.py From coffeegrindsize with MIT License | 6 votes |
def strftime(self, dt, fmt=None): """ Refer to documentation for :meth:`datetime.datetime.strftime` *fmt* is a :meth:`datetime.datetime.strftime` format string. Warning: For years before 1900, depending upon the current locale it is possible that the year displayed with %x might be incorrect. For years before 100, %y and %Y will yield zero-padded strings. """ if fmt is None: fmt = self.fmt fmt = self.illegal_s.sub(r"\1", fmt) fmt = fmt.replace("%s", "s") if dt.year >= 1900: # Note: in python 3.3 this is okay for years >= 1000, # refer to http://bugs.python.org/issue1777412 return cbook.unicode_safe(dt.strftime(fmt)) return self.strftime_pre_1900(dt, fmt)
Example #2
Source File: dates.py From CogAlg with MIT License | 6 votes |
def autoscale(self): """ Set the view limits to include the data range. """ dmin, dmax = self.datalim_to_dt() ymin = self.base.le(dmin.year) ymax = self.base.ge(dmax.year) vmin = dmin.replace(year=ymin, **self.replaced) vmin = vmin.astimezone(self.tz) vmax = dmax.replace(year=ymax, **self.replaced) vmax = vmax.astimezone(self.tz) vmin = date2num(vmin) vmax = date2num(vmax) return self.nonsingular(vmin, vmax)
Example #3
Source File: dates.py From CogAlg with MIT License | 6 votes |
def tick_values(self, vmin, vmax): ymin = self.base.le(vmin.year) * self.base.step ymax = self.base.ge(vmax.year) * self.base.step vmin = vmin.replace(year=ymin, **self.replaced) if hasattr(self.tz, 'localize'): # look after pytz if not vmin.tzinfo: vmin = self.tz.localize(vmin, is_dst=True) ticks = [vmin] while True: dt = ticks[-1] if dt.year >= ymax: return date2num(ticks) year = dt.year + self.base.step dt = dt.replace(year=year, **self.replaced) if hasattr(self.tz, 'localize'): # look after pytz if not dt.tzinfo: dt = self.tz.localize(dt, is_dst=True) ticks.append(dt)
Example #4
Source File: dates.py From CogAlg with MIT License | 6 votes |
def __init__(self, base=1, month=1, day=1, tz=None): """ Mark years that are multiple of base on a given month and day (default jan 1). """ DateLocator.__init__(self, tz) self.base = ticker._Edge_integer(base, 0) self.replaced = {'month': month, 'day': day, 'hour': 0, 'minute': 0, 'second': 0, } if not hasattr(tz, 'localize'): # if tz is pytz, we need to do this w/ the localize fcn, # otherwise datetime.replace works fine... self.replaced['tzinfo'] = tz
Example #5
Source File: dates.py From CogAlg with MIT License | 6 votes |
def strftime(self, dt, fmt=None): """ Refer to documentation for :meth:`datetime.datetime.strftime` *fmt* is a :meth:`datetime.datetime.strftime` format string. Warning: For years before 1900, depending upon the current locale it is possible that the year displayed with %x might be incorrect. For years before 100, %y and %Y will yield zero-padded strings. """ if fmt is None: fmt = self.fmt fmt = self.illegal_s.sub(r"\1", fmt) fmt = fmt.replace("%s", "s") if dt.year >= 1900: # Note: in python 3.3 this is okay for years >= 1000, # refer to http://bugs.python.org/issue1777412 return cbook.unicode_safe(dt.strftime(fmt)) return self.strftime_pre_1900(dt, fmt)
Example #6
Source File: dates.py From coffeegrindsize with MIT License | 6 votes |
def autoscale(self): """ Set the view limits to include the data range. """ dmin, dmax = self.datalim_to_dt() ymin = self.base.le(dmin.year) ymax = self.base.ge(dmax.year) vmin = dmin.replace(year=ymin, **self.replaced) vmin = vmin.astimezone(self.tz) vmax = dmax.replace(year=ymax, **self.replaced) vmax = vmax.astimezone(self.tz) vmin = date2num(vmin) vmax = date2num(vmax) return self.nonsingular(vmin, vmax)
Example #7
Source File: dates.py From coffeegrindsize with MIT License | 6 votes |
def tick_values(self, vmin, vmax): ymin = self.base.le(vmin.year) * self.base.step ymax = self.base.ge(vmax.year) * self.base.step vmin = vmin.replace(year=ymin, **self.replaced) if hasattr(self.tz, 'localize'): # look after pytz if not vmin.tzinfo: vmin = self.tz.localize(vmin, is_dst=True) ticks = [vmin] while True: dt = ticks[-1] if dt.year >= ymax: return date2num(ticks) year = dt.year + self.base.step dt = dt.replace(year=year, **self.replaced) if hasattr(self.tz, 'localize'): # look after pytz if not dt.tzinfo: dt = self.tz.localize(dt, is_dst=True) ticks.append(dt)
Example #8
Source File: dates.py From coffeegrindsize with MIT License | 6 votes |
def __init__(self, base=1, month=1, day=1, tz=None): """ Mark years that are multiple of base on a given month and day (default jan 1). """ DateLocator.__init__(self, tz) self.base = ticker._Edge_integer(base, 0) self.replaced = {'month': month, 'day': day, 'hour': 0, 'minute': 0, 'second': 0, } if not hasattr(tz, 'localize'): # if tz is pytz, we need to do this w/ the localize fcn, # otherwise datetime.replace works fine... self.replaced['tzinfo'] = tz
Example #9
Source File: utils.py From Ocean-Data-Map-Project with GNU General Public License v3.0 | 6 votes |
def datetime_to_timestamp(datetime: datetime.datetime, time_units: str): """Converts a given datetime object and time units string into a netcdf timestamp integer with UTC encoding. Arguments: datetime {datetime.datetime} -- some datetime object time_units {str} -- time units (e.g. 'seconds since 1950-01-01 00:00:00') Returns: [int] -- timestamp integer """ t = cftime.utime(time_units) datetime = datetime.replace(tzinfo=pytz.UTC) return t.date2num(datetime)
Example #10
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 6 votes |
def strftime(self, dt, fmt=None): """ Refer to documentation for :meth:`datetime.datetime.strftime` *fmt* is a :meth:`datetime.datetime.strftime` format string. Warning: For years before 1900, depending upon the current locale it is possible that the year displayed with %x might be incorrect. For years before 100, %y and %Y will yield zero-padded strings. """ if fmt is None: fmt = self.fmt fmt = self.illegal_s.sub(r"\1", fmt) fmt = fmt.replace("%s", "s") if dt.year >= 1900: # Note: in python 3.3 this is okay for years >= 1000, # refer to http://bugs.python.org/issue1777412 return cbook.unicode_safe(dt.strftime(fmt)) return self.strftime_pre_1900(dt, fmt)
Example #11
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 6 votes |
def __init__(self, base=1, month=1, day=1, tz=None): """ Mark years that are multiple of base on a given month and day (default jan 1). """ DateLocator.__init__(self, tz) self.base = ticker._Edge_integer(base, 0) self.replaced = {'month': month, 'day': day, 'hour': 0, 'minute': 0, 'second': 0, } if not hasattr(tz, 'localize'): # if tz is pytz, we need to do this w/ the localize fcn, # otherwise datetime.replace works fine... self.replaced['tzinfo'] = tz
Example #12
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 6 votes |
def autoscale(self): """ Set the view limits to include the data range. """ dmin, dmax = self.datalim_to_dt() ymin = self.base.le(dmin.year) ymax = self.base.ge(dmax.year) vmin = dmin.replace(year=ymin, **self.replaced) vmin = vmin.astimezone(self.tz) vmax = dmax.replace(year=ymax, **self.replaced) vmax = vmax.astimezone(self.tz) vmin = date2num(vmin) vmax = date2num(vmax) return self.nonsingular(vmin, vmax)
Example #13
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 6 votes |
def tick_values(self, vmin, vmax): ymin = self.base.le(vmin.year) * self.base.step ymax = self.base.ge(vmax.year) * self.base.step vmin = vmin.replace(year=ymin, **self.replaced) if hasattr(self.tz, 'localize'): # look after pytz if not vmin.tzinfo: vmin = self.tz.localize(vmin, is_dst=True) ticks = [vmin] while True: dt = ticks[-1] if dt.year >= ymax: return date2num(ticks) year = dt.year + self.base.step dt = dt.replace(year=year, **self.replaced) if hasattr(self.tz, 'localize'): # look after pytz if not dt.tzinfo: dt = self.tz.localize(dt, is_dst=True) ticks.append(dt)
Example #14
Source File: i18n.py From googleapps-message-recall with Apache License 2.0 | 5 votes |
def to_local_timezone(self, datetime): """Returns a datetime object converted to the local timezone. :param datetime: A ``datetime`` object. :returns: A ``datetime`` object normalized to a timezone. """ if datetime.tzinfo is None: datetime = datetime.replace(tzinfo=pytz.UTC) return self.tzinfo.normalize(datetime.astimezone(self.tzinfo))
Example #15
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 5 votes |
def _update_rrule(self, **kwargs): tzinfo = self._base_tzinfo # rrule does not play nicely with time zones - especially pytz time # zones, it's best to use naive zones and attach timezones once the # datetimes are returned if 'dtstart' in kwargs: dtstart = kwargs['dtstart'] if dtstart.tzinfo is not None: if tzinfo is None: tzinfo = dtstart.tzinfo else: dtstart = dtstart.astimezone(tzinfo) kwargs['dtstart'] = dtstart.replace(tzinfo=None) if 'until' in kwargs: until = kwargs['until'] if until.tzinfo is not None: if tzinfo is not None: until = until.astimezone(tzinfo) else: raise ValueError('until cannot be aware if dtstart ' 'is naive and tzinfo is None') kwargs['until'] = until.replace(tzinfo=None) self._construct = kwargs.copy() self._tzinfo = tzinfo self._rrule = rrule(**self._construct)
Example #16
Source File: dates.py From CogAlg with MIT License | 5 votes |
def _attach_tzinfo(self, dt, tzinfo): # pytz zones are attached by "localizing" the datetime if hasattr(tzinfo, 'localize'): return tzinfo.localize(dt, is_dst=True) return dt.replace(tzinfo=tzinfo)
Example #17
Source File: dates.py From CogAlg with MIT License | 5 votes |
def _update_rrule(self, **kwargs): tzinfo = self._base_tzinfo # rrule does not play nicely with time zones - especially pytz time # zones, it's best to use naive zones and attach timezones once the # datetimes are returned if 'dtstart' in kwargs: dtstart = kwargs['dtstart'] if dtstart.tzinfo is not None: if tzinfo is None: tzinfo = dtstart.tzinfo else: dtstart = dtstart.astimezone(tzinfo) kwargs['dtstart'] = dtstart.replace(tzinfo=None) if 'until' in kwargs: until = kwargs['until'] if until.tzinfo is not None: if tzinfo is not None: until = until.astimezone(tzinfo) else: raise ValueError('until cannot be aware if dtstart ' 'is naive and tzinfo is None') kwargs['until'] = until.replace(tzinfo=None) self._construct = kwargs.copy() self._tzinfo = tzinfo self._rrule = rrule(**self._construct)
Example #18
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 5 votes |
def _attach_tzinfo(self, dt, tzinfo): # pytz zones are attached by "localizing" the datetime if hasattr(tzinfo, 'localize'): return tzinfo.localize(dt, is_dst=True) return dt.replace(tzinfo=tzinfo)
Example #19
Source File: dates.py From CogAlg with MIT License | 5 votes |
def _from_ordinalf(x, tz=None): """ Convert Gregorian float of the date, preserving hours, minutes, seconds and microseconds. Return value is a `.datetime`. The input date *x* is a float in ordinal days at UTC, and the output will be the specified `.datetime` object corresponding to that time in timezone *tz*, or if *tz* is ``None``, in the timezone specified in :rc:`timezone`. """ if tz is None: tz = _get_rc_timezone() ix, remainder = divmod(x, 1) ix = int(ix) if ix < 1: raise ValueError('Cannot convert {} to a date. This often happens if ' 'non-datetime values are passed to an axis that ' 'expects datetime objects.'.format(ix)) dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC) # Since the input date `x` float is unable to preserve microsecond # precision of time representation in non-antique years, the # resulting datetime is rounded to the nearest multiple of # `musec_prec`. A value of 20 is appropriate for current dates. musec_prec = 20 remainder_musec = int(round(remainder * MUSECONDS_PER_DAY / musec_prec) * musec_prec) # For people trying to plot with full microsecond precision, enable # an early-year workaround if x < 30 * 365: remainder_musec = int(round(remainder * MUSECONDS_PER_DAY)) # add hours, minutes, seconds, microseconds dt += datetime.timedelta(microseconds=remainder_musec) return dt.astimezone(tz) # a version of _from_ordinalf that can operate on numpy arrays
Example #20
Source File: dates.py From coffeegrindsize with MIT License | 5 votes |
def _attach_tzinfo(self, dt, tzinfo): # pytz zones are attached by "localizing" the datetime if hasattr(tzinfo, 'localize'): return tzinfo.localize(dt, is_dst=True) return dt.replace(tzinfo=tzinfo)
Example #21
Source File: dates.py From coffeegrindsize with MIT License | 5 votes |
def _update_rrule(self, **kwargs): tzinfo = self._base_tzinfo # rrule does not play nicely with time zones - especially pytz time # zones, it's best to use naive zones and attach timezones once the # datetimes are returned if 'dtstart' in kwargs: dtstart = kwargs['dtstart'] if dtstart.tzinfo is not None: if tzinfo is None: tzinfo = dtstart.tzinfo else: dtstart = dtstart.astimezone(tzinfo) kwargs['dtstart'] = dtstart.replace(tzinfo=None) if 'until' in kwargs: until = kwargs['until'] if until.tzinfo is not None: if tzinfo is not None: until = until.astimezone(tzinfo) else: raise ValueError('until cannot be aware if dtstart ' 'is naive and tzinfo is None') kwargs['until'] = until.replace(tzinfo=None) self._construct = kwargs.copy() self._tzinfo = tzinfo self._rrule = rrule(**self._construct)
Example #22
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 5 votes |
def _from_ordinalf(x, tz=None): """ Convert Gregorian float of the date, preserving hours, minutes, seconds and microseconds. Return value is a `.datetime`. The input date *x* is a float in ordinal days at UTC, and the output will be the specified `.datetime` object corresponding to that time in timezone *tz*, or if *tz* is ``None``, in the timezone specified in :rc:`timezone`. """ if tz is None: tz = _get_rc_timezone() ix, remainder = divmod(x, 1) ix = int(ix) if ix < 1: raise ValueError('Cannot convert {} to a date. This often happens if ' 'non-datetime values are passed to an axis that ' 'expects datetime objects.'.format(ix)) dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC) # Since the input date `x` float is unable to preserve microsecond # precision of time representation in non-antique years, the # resulting datetime is rounded to the nearest multiple of # `musec_prec`. A value of 20 is appropriate for current dates. musec_prec = 20 remainder_musec = int(round(remainder * MUSECONDS_PER_DAY / musec_prec) * musec_prec) # For people trying to plot with full microsecond precision, enable # an early-year workaround if x < 30 * 365: remainder_musec = int(round(remainder * MUSECONDS_PER_DAY)) # add hours, minutes, seconds, microseconds dt += datetime.timedelta(microseconds=remainder_musec) return dt.astimezone(tz) # a version of _from_ordinalf that can operate on numpy arrays
Example #23
Source File: dates.py From coffeegrindsize with MIT License | 5 votes |
def _from_ordinalf(x, tz=None): """ Convert Gregorian float of the date, preserving hours, minutes, seconds and microseconds. Return value is a `.datetime`. The input date *x* is a float in ordinal days at UTC, and the output will be the specified `.datetime` object corresponding to that time in timezone *tz*, or if *tz* is ``None``, in the timezone specified in :rc:`timezone`. """ if tz is None: tz = _get_rc_timezone() ix, remainder = divmod(x, 1) ix = int(ix) if ix < 1: raise ValueError('Cannot convert {} to a date. This often happens if ' 'non-datetime values are passed to an axis that ' 'expects datetime objects.'.format(ix)) dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC) # Since the input date `x` float is unable to preserve microsecond # precision of time representation in non-antique years, the # resulting datetime is rounded to the nearest multiple of # `musec_prec`. A value of 20 is appropriate for current dates. musec_prec = 20 remainder_musec = int(round(remainder * MUSECONDS_PER_DAY / musec_prec) * musec_prec) # For people trying to plot with full microsecond precision, enable # an early-year workaround if x < 30 * 365: remainder_musec = int(round(remainder * MUSECONDS_PER_DAY)) # add hours, minutes, seconds, microseconds dt += datetime.timedelta(microseconds=remainder_musec) return dt.astimezone(tz) # a version of _from_ordinalf that can operate on numpy arrays
Example #24
Source File: utils.py From Ocean-Data-Map-Project with GNU General Public License v3.0 | 5 votes |
def time_index_to_datetime(timestamps, time_units: str): if isinstance(timestamps, np.ndarray): timestamps = timestamps.tolist() if not isinstance(timestamps, list): timestamps = [timestamps] result = [cftime.num2date(timestamp, time_units).replace(tzinfo=pytz.UTC) for timestamp in timestamps] if isinstance(result[0], list): return list(itertools.chain(*result)) return result
Example #25
Source File: i18n.py From googleapps-message-recall with Apache License 2.0 | 5 votes |
def to_utc(self, datetime): """Returns a datetime object converted to UTC and without tzinfo. :param datetime: A ``datetime`` object. :returns: A naive ``datetime`` object (no timezone), converted to UTC. """ if datetime.tzinfo is None: datetime = self.tzinfo.localize(datetime) return datetime.astimezone(pytz.UTC).replace(tzinfo=None)
Example #26
Source File: dates.py From CogAlg with MIT License | 4 votes |
def strftime_pre_1900(self, dt, fmt=None): """Call time.strftime for years before 1900 by rolling forward a multiple of 28 years. *fmt* is a :func:`strftime` format string. Dalke: I hope I did this math right. Every 28 years the calendar repeats, except through century leap years excepting the 400 year leap years. But only if you're using the Gregorian calendar. """ if fmt is None: fmt = self.fmt # Since python's time module's strftime implementation does not # support %f microsecond (but the datetime module does), use a # regular expression substitution to replace instances of %f. # Note that this can be useful since python's floating-point # precision representation for datetime causes precision to be # more accurate closer to year 0 (around the year 2000, precision # can be at 10s of microseconds). fmt = re.sub(r'((^|[^%])(%%)*)%f', r'\g<1>{0:06d}'.format(dt.microsecond), fmt) year = dt.year # For every non-leap year century, advance by # 6 years to get into the 28-year repeat cycle delta = 2000 - year off = 6 * (delta // 100 + delta // 400) year = year + off # Move to between the years 1973 and 2000 year1 = year + ((2000 - year) // 28) * 28 year2 = year1 + 28 timetuple = dt.timetuple() # Generate timestamp string for year and year+28 s1 = time.strftime(fmt, (year1,) + timetuple[1:]) s2 = time.strftime(fmt, (year2,) + timetuple[1:]) # Replace instances of respective years (both 2-digit and 4-digit) # that are located at the same indexes of s1, s2 with dt's year. # Note that C++'s strftime implementation does not use padded # zeros or padded whitespace for %y or %Y for years before 100, but # uses padded zeros for %x. (For example, try the runnable examples # with .tm_year in the interval [-1900, -1800] on # http://en.cppreference.com/w/c/chrono/strftime.) For ease of # implementation, we always use padded zeros for %y, %Y, and %x. s1, s2 = self._replace_common_substr(s1, s2, "{0:04d}".format(year1), "{0:04d}".format(year2), "{0:04d}".format(dt.year)) s1, s2 = self._replace_common_substr(s1, s2, "{0:02d}".format(year1 % 100), "{0:02d}".format(year2 % 100), "{0:02d}".format(dt.year % 100)) return cbook.unicode_safe(s1)
Example #27
Source File: dates.py From coffeegrindsize with MIT License | 4 votes |
def strftime_pre_1900(self, dt, fmt=None): """Call time.strftime for years before 1900 by rolling forward a multiple of 28 years. *fmt* is a :func:`strftime` format string. Dalke: I hope I did this math right. Every 28 years the calendar repeats, except through century leap years excepting the 400 year leap years. But only if you're using the Gregorian calendar. """ if fmt is None: fmt = self.fmt # Since python's time module's strftime implementation does not # support %f microsecond (but the datetime module does), use a # regular expression substitution to replace instances of %f. # Note that this can be useful since python's floating-point # precision representation for datetime causes precision to be # more accurate closer to year 0 (around the year 2000, precision # can be at 10s of microseconds). fmt = re.sub(r'((^|[^%])(%%)*)%f', r'\g<1>{0:06d}'.format(dt.microsecond), fmt) year = dt.year # For every non-leap year century, advance by # 6 years to get into the 28-year repeat cycle delta = 2000 - year off = 6 * (delta // 100 + delta // 400) year = year + off # Move to between the years 1973 and 2000 year1 = year + ((2000 - year) // 28) * 28 year2 = year1 + 28 timetuple = dt.timetuple() # Generate timestamp string for year and year+28 s1 = time.strftime(fmt, (year1,) + timetuple[1:]) s2 = time.strftime(fmt, (year2,) + timetuple[1:]) # Replace instances of respective years (both 2-digit and 4-digit) # that are located at the same indexes of s1, s2 with dt's year. # Note that C++'s strftime implementation does not use padded # zeros or padded whitespace for %y or %Y for years before 100, but # uses padded zeros for %x. (For example, try the runnable examples # with .tm_year in the interval [-1900, -1800] on # http://en.cppreference.com/w/c/chrono/strftime.) For ease of # implementation, we always use padded zeros for %y, %Y, and %x. s1, s2 = self._replace_common_substr(s1, s2, "{0:04d}".format(year1), "{0:04d}".format(year2), "{0:04d}".format(dt.year)) s1, s2 = self._replace_common_substr(s1, s2, "{0:02d}".format(year1 % 100), "{0:02d}".format(year2 % 100), "{0:02d}".format(dt.year % 100)) return cbook.unicode_safe(s1)
Example #28
Source File: dates.py From python3_ios with BSD 3-Clause "New" or "Revised" License | 4 votes |
def strftime_pre_1900(self, dt, fmt=None): """Call time.strftime for years before 1900 by rolling forward a multiple of 28 years. *fmt* is a :func:`strftime` format string. Dalke: I hope I did this math right. Every 28 years the calendar repeats, except through century leap years excepting the 400 year leap years. But only if you're using the Gregorian calendar. """ if fmt is None: fmt = self.fmt # Since python's time module's strftime implementation does not # support %f microsecond (but the datetime module does), use a # regular expression substitution to replace instances of %f. # Note that this can be useful since python's floating-point # precision representation for datetime causes precision to be # more accurate closer to year 0 (around the year 2000, precision # can be at 10s of microseconds). fmt = re.sub(r'((^|[^%])(%%)*)%f', r'\g<1>{0:06d}'.format(dt.microsecond), fmt) year = dt.year # For every non-leap year century, advance by # 6 years to get into the 28-year repeat cycle delta = 2000 - year off = 6 * (delta // 100 + delta // 400) year = year + off # Move to between the years 1973 and 2000 year1 = year + ((2000 - year) // 28) * 28 year2 = year1 + 28 timetuple = dt.timetuple() # Generate timestamp string for year and year+28 s1 = time.strftime(fmt, (year1,) + timetuple[1:]) s2 = time.strftime(fmt, (year2,) + timetuple[1:]) # Replace instances of respective years (both 2-digit and 4-digit) # that are located at the same indexes of s1, s2 with dt's year. # Note that C++'s strftime implementation does not use padded # zeros or padded whitespace for %y or %Y for years before 100, but # uses padded zeros for %x. (For example, try the runnable examples # with .tm_year in the interval [-1900, -1800] on # http://en.cppreference.com/w/c/chrono/strftime.) For ease of # implementation, we always use padded zeros for %y, %Y, and %x. s1, s2 = self._replace_common_substr(s1, s2, "{0:04d}".format(year1), "{0:04d}".format(year2), "{0:04d}".format(dt.year)) s1, s2 = self._replace_common_substr(s1, s2, "{0:02d}".format(year1 % 100), "{0:02d}".format(year2 % 100), "{0:02d}".format(dt.year % 100)) return cbook.unicode_safe(s1)