日期时间对象是包含来自日期对象和时间对象的所有信息的单个对象。 与日期对象一样,日期时间假定当前的公历在两个方向上扩展; 与时间对象一样,datetime 假定每天正好有 3600*24 秒。

构造函数:

class datetime.datetime(yearmonthdayhour=0minute=0second=0microsecond=0tzinfo=None*fold=0)
年、月和日参数是必需的。 tzinfo可能是None或子类的一个实例tzinfo。其余参数必须是以下范围内的整数:

  • MINYEAR <= year <= MAXYEAR,
  • 1 <= month <= 12,
  • 1 <= day <= number of days in the given month and year,
  • 0 <= hour < 24,
  • 0 <= minute < 60,
  • 0 <= second < 60,
  • 0 <= microsecond < 1000000,
  • fold in [0, 1].

如果给出了超出这些范围的参数,ValueError则引发。

3.6 新版功能:添加了fold参数。

其他构造函数,所有类方法:

classmethod datetime.today()
返回当前的本地日期时间,使用 tzinfo None。 这相当于 datetime.fromtimestamp(time.time())。 另请参见 now()、fromtimestamp()。
classmethod datetime.now(tz=None)
返回当前的本地日期和时间。 如果可选参数 tz 为 None 或未指定,则类似于 today(),但如果可能,提供比通过 time.time() 时间戳获得的精度更高的精度(例如,这可能在提供 C gettimeofday() 函数)。

如果 tz 不是 None,它必须是 tzinfo 子类的实例,并且当前日期和时间被转换为 tz 的时区。 在这种情况下,结果等效于 tz.fromutc(datetime.utcnow().replace(tzinfo=tz))。 另请参见 today()、utcnow()。

classmethod datetime.utcnow()
使用 tzinfo None 返回当前的 UTC 日期和时间。 这类似于 now(),但返回当前 UTC 日期和时间,作为一个简单的 datetime 对象。 可以通过调用 datetime.now(timezone.utc) 来获取已知的当前 UTC 日期时间。 参见 now()。
classmethod datetime.fromtimestamp(timestamptz=None)
返回POSIX时间戳对应的本地日期时间,如time.time()返回。如果可选参数 tz 为 None 或未指定,则时间戳转换为平台的本地日期和时间,并且返回的 datetime 对象是 naive。

如果 tz 不是 None ,它必须是 tzinfo 子类的实例,并且时间戳转换为 tz 的时区。在这种情况下,结果等同于 tz.fromutc(datetime.utcfromtimestamp(timestamp).replace(tzinfo=tz))。

如果时间戳超出平台 C localtime() 或 gmtime() 函数支持的值范围,并且 localtime() 或 gmtime() 失败时出现 OSError,则 fromtimestamp() 可能会引发 OverflowError。这通常被限制在 1970 年到 2038 年的年份。请注意,在时间戳概念中包含闰秒的非 POSIX 系统上,闰秒会被 fromtimestamp() 忽略,然后可能有两个不同的时间戳由一秒钟产生相同的日期时间对象。另请参见 utcfromtimestamp()。

在 3.3 版更改:如果时间戳超出平台 C localtime() 或 gmtime() 函数支持的值范围,则引发 OverflowError 而不是 ValueError。在 localtime() 或 gmtime() 失败时引发 OSError 而不是 ValueError。

在 3.6 版更改: fromtimestamp() 可能返回折叠设置为 1 的实例。

classmethod datetime.utcfromtimestamp(timestamp)
返回与 POSIX 时间戳对应的 UTC 日期时间,使用 tzinfo None。 如果时间戳超出平台 C gmtime() 函数支持的值范围,这可能会引发 OverflowError,并且在 gmtime() 失败时出现 OSError。 这通常被限制在 1970 年到 2038 年的年份。

要获取可感知的日期时间对象,请调用 fromtimestamp():

datetime.fromtimestamp(timestamp, timezone.utc)

在 POSIX 兼容的平台上,它等价于以下表达式:

datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp)

除了后一个公式始终支持完整的年份范围:MINYEAR 和 MAXYEAR 之间。

在 3.3 版更改:如果时间戳超出平台 C gmtime() 函数支持的值范围,则引发 OverflowError 而不是 ValueError。 在 gmtime() 失败时引发 OSError 而不是 ValueError。

classmethod datetime.fromordinal(ordinal)
返回对应于预测公历序数的日期时间,其中第 1 年的 1 月 1 日有序数 1。除非 1 <= ordinal <= datetime.max.toordinal(),否则会引发 ValueError。 结果的时分秒微秒全为0,tzinfo为None。
classmethod datetime.combine(datetimetzinfo=self.tzinfo)
返回一个新的 datetime 对象,其日期分量等于给定日期对象的日期分量,其时间分量等于给定时间对象的时间分量。 如果提供了 tzinfo 参数,则其值用于设置结果的 tzinfo 属性,否则使用 time 参数的 tzinfo 属性。

对于任何日期时间对象 d,d == datetime.combine(d.date(), d.time(), d.tzinfo)。 如果 date 是 datetime 对象,则忽略其时间组件和 tzinfo 属性。

在 3.6 版更改: 添加了 tzinfo 参数。

classmethod datetime.fromisoformatdate_string 

以 date.isoformat() 和 datetime.isoformat() 发出的格式之一返回与 date_string 对应的日期时间。 具体来说,此函数支持格式为 YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]] 的字符串 , 其中 * 可以匹配任何单个字符。

注意 这不支持解析任意 ISO 8601 字符串 – 它仅用作 datetime.isoformat() 的逆操作。 第三方包 dateutil 中提供了功能更全的 ISO 8601 解析器 dateutil.parser.isoparse。
3.7 版中的新功能。

classmethod datetime.strptime(date_string)
返回一个date_string对应的datetime,根据格式解析。 这等效于 datetime(*(time.strptime(date_string, format)[0:6]))。 如果 date_string 和 format 不能被 time.strptime() 解析,或者它返回的值不是时间元组,则会引发 ValueError。 有关格式化指令的完整列表,请参阅 strftime() 和 strptime() 行为。

类属性:

datetime.min
最早可表示的datetime,.datetime(MINYEAR, 1, 1, tzinfo=None)
datetime.max
最新的可代表datetime, .datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None)
datetime.resolution
datetime不相等对象 之间的最小可能差异, timedelta(microseconds=1)

实例属性(只读):

datetime.year
介于MINYEARMAXYEAR包容之间。
datetime.month
介于 1 和 12 之间。
datetime.day
介于 1 和给定年份的给定月份的天数之间。
datetime.hour
range(24).
datetime.minute
range(60).
datetime.second
range(60).
datetime.microsecond
range(1000000).
datetime.tzinfo
对象作为tzinfo参数传递给datetime构造函数,或者None如果没有传递。
datetime.fold
在 [0, 1] 中。 用于在重复间隔期间消除壁时间的歧义。 (当时钟在夏令时结束时回滚或由于政治原因减少当前区域的 UTC 偏移量时,会出现重复间隔。)值 0 (1) 表示两个时刻中较早(较晚)的时刻 相同的墙上时间表示。

支持的操作:

操作 结果
datetime2 = datetime1 + timedelta (1)
datetime2 = datetime1 - timedelta (2)
timedelta = datetime1 - datetime2 (3)
datetime1 < datetime2 比较datetime为 datetime。(4)
  1. datetime2 是从 datetime1 中删除的 timedelta 的持续时间,如果timedelta.days> 0 则向前移动,如果timedelta.days< 0 则向后移动。结果tzinfo与输入 datetime 具有相同的属性,并且 datetime2 – datetime1 == timedelta 之后。OverflowError如果 datetime2.year 小于MINYEAR或大于 MAXYEAR. 请注意,即使输入是感知对象,也不会进行时区调整。
  2. 计算 datetime2 使得 datetime2 + timedelta == datetime1。至于加法,结果与tzinfo输入的日期时间具有相同的属性,即使输入知道也不做时区调整。
  3. 仅当两个操作数都是幼稚的或两者都知道时,才定义datetime从 a中减去 a 。datetime如果一个是有意识的而另一个是天真的,TypeError则被提出。

    如果两者都是幼稚的,或者两者都知道并具有相同tzinfo的属性,tzinfo则忽略这些属性,结果是一个timedelta 对象t满足。在这种情况下,不进行时区调整。datetime2 + t == datetime1

    如果两者都知道并且具有不同的tzinfo属性,a-b则就像ab首先首先转换为天真的 UTC 日期时间一样。结果是实现永远不会溢出。(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())

  4. datetime1在时间上早于 datetime2时, datetime1被认为小于datetime2

    如果一个比较对象是幼稚的,而另一个是有意识的,TypeError 则在尝试进行顺序比较时引发。对于相等比较,天真的实例永远不会等于有意识的实例。

    如果两个比较对象都知道并且具有相同tzinfo的属性,则忽略公共tzinfo属性并比较基本日期时间。如果两个比较对象都知道并且具有不同tzinfo 的属性,则首先通过减去它们的 UTC 偏移量(从 获得self.utcoffset())来调整比较对象。

    在 3.3 版更改:幼稚实例和有意识实例之间的平等比较datetime 不会引发TypeError.

    笔记

    为了阻止比较回退到比较对象地址的默认方案,TypeError如果另一个比较对象也不是datetime对象,则通常会引发日期时间比较。但是, NotImplemented如果另一个比较具有 timetuple()属性,则返回。这个钩子为其他类型的日期对象提供了实现混合类型比较的机会。如果不是,则在将datetime 对象与不同类型的对象进行比较时,TypeError将引发,除非比较是==or !=。后一种情况分别返回 Falseor True

datetime对象可以用作字典键。在布尔上下文中,所有datetime对象都被认为是真实的。

实例方法:

datetime.date()
返回date具有相同年月日的对象。
datetime.time() 
返回time具有相同时、分、秒、微秒和折叠的对象。 tzinfoNone。另见方法timetz()

在 3.6 版更改:折叠值被复制到返回的time对象。

datetime.timetz()
返回time具有相同小时、分钟、秒、微秒、折叠和 tzinfo 属性的对象。另见方法time()

在 3.6 版更改:折叠值被复制到返回的time对象。

datetime.replace(year=self.yearmonth=self.monthday=self.dayhour=self.hourminute=self.minutesecond=self.secondmicrosecond=self.microsecondtzinfo=self.tzinfo* fold=0)
返回具有相同属性的日期时间,但那些由指定的关键字参数赋予新值的属性除外。请注意, tzinfo=None可以指定从感知的日期时间创建一个简单的日期时间,而不转换日期和时间数据。

3.6 新版功能:添加了fold参数。

datetime.astimezone(tz=None)
返回一个datetime具有新tzinfo属性tz的对象,调整日期和时间数据,使结果与self相同的 UTC 时间 ,但在tz的本地时间。

如果提供,则tz必须是tzinfo子类的实例,并且其 utcoffset()dst()方法不得返回None。如果self 是幼稚的,则假定它代表系统时区中的时间。

如果不带参数(或带tz=None)调用,系统本地时区被假定为目标时区。转换后的日期时间实例的.tzinfo属性将设置为具有timezone 从操作系统获取的区域名称和偏移量的实例。

如果self.tzinfotzself.astimezone(tz)则等于self:不执行日期或时间数据的调整。否则结果是时区tz中的本地时间,表示与self相同的 UTC 时间:之后 ,将具有与 相同的日期和时间数据。astz = dt.astimezone(tz)astz - astz.utcoffset()dt - dt.utcoffset()

如果您只想将时区对象tz附加到日期时间dt而不调整日期和时间数据,请使用dt.replace(tzinfo=tz). 如果您只想从知道的日期时间dt中删除时区对象而不转换日期和时间数据,请使用dt.replace(tzinfo=None).

请注意,tzinfo.fromutc()可以在 tzinfo子类中重写默认方法以影响astimezone(). 忽略错误情况,astimezone()行为如下:

def astimezone(self, tz):
    if self.tzinfo is tz:
        return self
    # Convert self to UTC, and attach the new time zone object.
    utc = (self - self.utcoffset()).replace(tzinfo=tz)
    # Convert from UTC to tz's local time.
    return tz.fromutc(utc)

在 3.3 版更改:现在可以省略tz 。

在 3.6 版更改:astimezone()现在可以在假定代表系统本地时间的幼稚实例上调用该方法。

datetime.utcoffset()
如果tzinfoNone,则返回None,否则返回 self.tzinfo.utcoffset(self),如果后者不返回Nonetimedelta大小小于一天的对象,则引发异常。

在 3.7 版更改: UTC 偏移量不限于整数分钟。

datetime.dst()
如果tzinfoNone,则返回None,否则返回 self.tzinfo.dst(self),如果后者不返回 Nonetimedelta大小小于一天的对象,则引发异常。

在 3.7 版更改: DST 偏移量不限于整数分钟。

datetime.tzname()
如果tzinfoNone,返回None,否则返回 self.tzinfo.tzname(self),如果后者不返回 None或字符串对象,则引发异常,
datetime.timetuple()
返回一个 time.struct_time,例如由 time.localtime() 返回。 d.timetuple() 等价于 time.struct_time((d.year, d.month, d.day, d.hour, d.minute, d.second, d.weekday(), yday, dst)),其中 yday = d.toordinal() – date(d.year, 1, 1).toordinal() + 1 是当年的天数,从 1 开始表示 1 月 1 日。 结果的tm_isdst标志根据dst()方法设置:tzinfo为None或dst()返回None,tm_isdst设置为-1; 否则,如果 dst() 返回非零值,则 tm_isdst 设置为 1; 否则 tm_isdst 设置为 0。
datetime.utctimetuple()
如果 datetime 实例 d 是幼稚的,这与 d.timetuple() 相同,除了 tm_isdst 被强制为 0 而不管 d.dst() 返回什么。 DST 永远不会在 UTC 时间生效。

如果 d 知道,则通过减去 d.utcoffset() 将 d 归一化为 UTC 时间,并返回归一化时间的 time.struct_time。 tm_isdst 被强制为 0。请注意,如果 d.year 为 MINYEAR 或 MAXYEAR 并且 UTC 调整超出一年边界,则可能会引发 OverflowError。

datetime.toordinal()
返回日期的预测公历序数。与 相同 self.date().toordinal()
datetime.timestamp()
返回datetime 实例对应的 POSIX 时间戳。返回值floattime.time().

假定朴素datetime实例表示本地时间,并且此方法依赖于平台 Cmktime() 函数来执行转换。由于datetime 支持比许多平台更广泛的值mktime(),因此此方法可能会OverflowError在过去或很长时间内提高。

对于有意识datetime的实例,返回值计算为:

(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()

3.3 版中的新功能。

在 3.6 版更改:timestamp()方法使用该fold属性来消除重复间隔期间的时间歧义。

笔记

没有方法可以直接从datetime表示 UTC 时间的简单实例中获取 POSIX 时间戳。如果您的应用程序使用此约定并且您的系统时区未设置为 UTC,您可以通过提供以下内容来获取 POSIX 时间戳 tzinfo=timezone.utc

timestamp = dt.replace(tzinfo=timezone.utc).timestamp()

或通过直接计算时间戳:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)
datetime.weekday()
以整数形式返回星期几,其中星期一为 0,星期日为 6。同self.date().weekday(). 另请参阅isoweekday()
datetime.isoweekday()
以整数形式返回星期几,其中星期一为 1,星期日为 7。同self.date().isoweekday(). 另请参阅weekday(), isocalendar()
datetime.isocalendar()
返回一个 3 元组(ISO 年、ISO 周数、ISO 工作日)。与 相同 self.date().isocalendar()
datetime.isoformat(sep=’T’timespec=’auto’)
返回一个表示日期和时间的字符串,采用 ISO 8601 格式,YYYY-MM-DDTHH:MM:SS.ffffff,如果microsecond为 0,则返回 YYYY-MM-DDTHH:MM:SS

如果utcoffset()没有返回None,则附加一个字符串,给出 UTC 偏移量:YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]] 或者,如果microsecond 是 0 YYYY-MM-DDTHH:MM :SS+HH:MM[:SS[.ffffff]]。

可选参数sep(默认'T')是一个单字符分隔符,位于结果的日期和时间部分之间。例如,

from datetime import tzinfo, timedelta, datetime
class TZ(tzinfo):
    def utcoffset(self, dt): return timedelta(minutes=-399)

datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'

可选参数timespec指定要包含的时间附加组件的数量(默认为'auto')。它可以是以下之一:

  • 'auto': 如果微秒为 0,则与“秒”相同,否则与“微秒”相同。
  • 'hours': 包含hour在两位数的 HH 格式中。
  • 'minutes': 包括hourminute以 HH:MM 格式。
  • 'seconds': 包括hourminute, 和second HH:MM:SS 格式。
  • 'milliseconds':包括全时,但将小数秒部分截断为毫秒。HH:MM:SS.sss 格式。
  • 'microseconds': 包括 HH:MM:SS.ffffff 格式的全职。

笔记

排除的时间分量被截断,而不是四舍五入。

ValueError将在无效的timespec参数上引发。

from datetime import datetime
datetime.now().isoformat(timespec='minutes')   
'2002-12-25T00:00'
dt = datetime(2015, 1, 1, 12, 30, 59, 0)
dt.isoformat(timespec='microseconds')
'2015-01-01T12:30:59.000000'

3.6 新版功能:添加了timespec参数。

datetime.__str__()
对于日期时间实例 d,str(d) 等价于 d.isoformat(”)。
datetime.ctime()
返回一个表示日期和时间的字符串,例如 datetime(2002, 12, 4, 20, 30, 40).ctime() == ‘Wed Dec 4 20:30:40 2002’。 d.ctime() 等效于 time.ctime(time.mktime(d.timetuple())) 平台上的原生 C ctime() 函数(由 time.ctime() 调用,但由 datetime.ctime() 调用) not invoke) 符合 C 标准。
datetime.strftime(format)
返回一个表示日期和时间的字符串,由显式格式字符串控制。有关格式化指令的完整列表,请参阅 strftime() 和 strptime() 行为
datetime.__format__(format)
与 相同datetime.strftime()。这使得可以datetime格式化字符串文字中以及在使用str.format(). 有关格式化指令的完整列表,请参阅 strftime() 和 strptime() 行为

使用日期时间对象的示例:

>>> from datetime import datetime, date, time
>>> # Using datetime.combine()
>>> d = date(2005, 7, 14)
>>> t = time(12, 30)
>>> datetime.combine(d, t)
datetime.datetime(2005, 7, 14, 12, 30)
>>> # Using datetime.now() or datetime.utcnow()
>>> datetime.now()   
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> datetime.utcnow()   
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060)
>>> # Using datetime.strptime()
>>> dt = datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
>>> dt
datetime.datetime(2006, 11, 21, 16, 30)
>>> # Using datetime.timetuple() to get tuple of all attributes
>>> tt = dt.timetuple()
>>> for it in tt:   
...     print(it)
...
2006    # year
11      # month
21      # day
16      # hour
30      # minute
0       # second
1       # weekday (0 = Monday)
325     # number of days since 1st January
-1      # dst - method tzinfo.dst() returned None
>>> # Date in ISO format
>>> ic = dt.isocalendar()
>>> for it in ic:   
...     print(it)
...
2006    # ISO year
47      # ISO week
2       # ISO weekday
>>> # Formatting datetime
>>> dt.strftime("%A, %d. %B %Y %I:%M%p")
'Tuesday, 21. November 2006 04:30PM'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}, the {3} is {0:%I:%M%p}.'.format(dt, "day", "month", "time")
'The day is 21, the month is November, the time is 04:30PM.'

将日期时间与 tzinfo 一起使用:

from datetime import timedelta, datetime, tzinfo, timezone
class KabulTz(tzinfo):
    # Kabul used +4 until 1945, when they moved to +4:30
    UTC_MOVE_DATE = datetime(1944, 12, 31, 20, tzinfo=timezone.utc)
    def utcoffset(self, dt):
        if dt.year < 1945:
            return timedelta(hours=4)
        elif (1945, 1, 1, 0, 0) <= dt.timetuple()[:5] < (1945, 1, 1, 0, 30):
            # If dt falls in the imaginary range, use fold to decide how
            # to resolve. See PEP495
            return timedelta(hours=4, minutes=(30 if dt.fold else 0))
        else:
            return timedelta(hours=4, minutes=30)

    def fromutc(self, dt):
        # A custom implementation is required for fromutc as
        # the input to this function is a datetime with utc values
        # but with a tzinfo set to self
        # See datetime.astimezone or fromtimestamp

        # Follow same validations as in datetime.tzinfo
        if not isinstance(dt, datetime):
            raise TypeError("fromutc() requires a datetime argument")
        if dt.tzinfo is not self:
            raise ValueError("dt.tzinfo is not self")

        if dt.replace(tzinfo=timezone.utc) >= self.UTC_MOVE_DATE:
            return dt + timedelta(hours=4, minutes=30)
        else:
            return dt + timedelta(hours=4)

    def dst(self, dt):
        return timedelta(0)

    def tzname(self, dt):
        if dt >= self.UTC_MOVE_DATE:
            return "+04:30"
        else:
            return "+04"

    def  __repr__(self):
        return f"{self.__class__.__name__}()"

tz1 = KabulTz()
# Datetime before the change
dt1 = datetime(1900, 11, 21, 16, 30, tzinfo=tz1)
print(dt1.utcoffset())
4:00:00
# Datetime after the change
dt2 = datetime(2006, 6, 14, 13, 0, tzinfo=tz1)
print(dt2.utcoffset())
4:30:00
# Convert datetime to another time zone
dt3 = dt2.astimezone(timezone.utc)
dt3
datetime.datetime(2006, 6, 14, 8, 30, tzinfo=datetime.timezone.utc)
dt2
datetime.datetime(2006, 6, 14, 13, 0, tzinfo=KabulTz())
dt2.utctimetuple() == dt3.utctimetuple()
True