datetime-基本日期和时间类型

源代码: Lib/datetime.py


datetime模块提供用于处理日期和时间的类。

虽然支持日期和时间算术,但实现的重点是针对输出格式和操作的有效属性提取。

See also

  • Module calendar

  • 常规 calendar 相关Function。

  • Module time

  • 时间访问和转换。

  • Package dateutil

  • 具有扩展时区和解析支持的第三方库。

感知和天真的对象

根据日期和时间对象是否包含时区信息,可以将其分类为“感知”或“天真”。

有了足够的适用算法和政治时间调整知识(例如时区和夏时制信息),“感知”对象可以相对于其他感知对象定位自己。一个有意识的对象表示一个特定的 Moment,这个 Moment 是无法解释的。 [1]

天真的对象没有足够的信息来明确地相对于其他日期/时间对象定位自己。天真的对象是代表协调世界时(UTC),本地时间还是在其他时区中的时间,完全取决于程序,就像特定数字代表米,英里或质量取决于程序一样。天真的对象易于理解和使用,以忽略现实的某些方面为代价。

对于需要感知对象的应用程序,datetimetime对象具有可选的时区信息属性tzinfo,可以将其设置为抽象tzinfo类的子类的实例。这些tzinfo对象捕获有关 UTC 时间的偏移量,时区名称以及夏时制是否有效的信息。

datetime模块仅提供一个具体的tzinfo类,即timezone类。 timezone类可以表示与 UTC 具有固定偏移量的简单时区,例如 UTC 本身或北美 EST 和 EDT 时区。在更详细的级别上支持时区取决于应用程序。世界各地的时间调整规则更具政治性,而不是理性的,经常更改,除了 UTC 之外,没有适用于所有应用程序的标准。

Constants

datetime模块导出以下常量:

Available Types

3.2 版中的新Function。

这些类型的对象是不可变的。

Subclass relationships:

object
    timedelta
    tzinfo
        timezone
    time
    date
        datetime

Common Properties

datedatetimetimetimezone类型具有以下共同 Feature:

确定对象是感知的还是天真的

date类型的对象总是幼稚的。

类型timedatetime的对象可能是感知的或幼稚的。

datetime对象* d *知道以下两个条件是否成立:

否则,* d *天真。

time对象* t *知道以下两个条件是否成立:

否则,* t *是幼稚的。

有意识和天真之间的区别不适用于timedelta个对象。

timedelta Objects

timedelta对象代表持续时间,即两个日期或时间之间的差。

内部仅存储* day seconds microseconds *。参数将转换为以下单位:

然后将天,秒和微秒标准化,以使表示形式唯一

以下示例说明了如何将* days,* seconds microseconds *以外的任何参数“合并”并归一化为这三个结果属性:

>>> from datetime import timedelta
>>> delta = timedelta(
...     days=50,
...     seconds=27,
...     microseconds=10,
...     milliseconds=29000,
...     minutes=5,
...     hours=8,
...     weeks=2
... )
>>> # Only days, seconds, and microseconds remain
>>> delta
datetime.timedelta(days=64, seconds=29156, microseconds=10)

如果任何自变量是浮点型并且有分数微秒,则将所有自变量剩余的分数微秒相结合,并使用二分之一到偶数抢七的方法将其总和四舍五入到最接近的微秒。如果没有参数是浮点数,则转换和规范化过程是精确的(不会丢失任何信息)。

如果天的归一化值超出指定的范围,则将引发OverflowError

请注意,负值的标准化一开始可能令人惊讶。例如:

>>> from datetime import timedelta
>>> d = timedelta(microseconds=-1)
>>> (d.days, d.seconds, d.microseconds)
(-1, 86399, 999999)

Class attributes:

请注意,由于标准化,timedelta.max> -timedelta.min-timedelta.max不能表示为timedelta对象。

实例属性(只读):

Attribute Value
days -999999999 至 999999999(含)之间
seconds 0 至 86399(含)之间
microseconds 0 至 999999(含)之间

Supported operations:

Operation Result
t1 = t2 + t3 * t2 t3 的总和。之后 t1 - t2 * == * t3 t1 - t3 * == * t2 *为真。 (1)
t1 = t2 - t3 * t2 t3 的差。之后 t1 * == * t2 - t3 t2 * == * t1 * * t3 *为真。 (1)(6)
t1 = t2 * i or t1 = i * t2 Delta 乘以整数。之后,* t1 * // i == * t2 *为 true,前提是i != 0
通常,* t1 * * i == * t1 * (i-1) t1 *为 true。 (1)
t1 = t2 * f or t1 = f * t2 Delta 乘以浮点数。使用二分之一到四舍五入将结果四舍五入到 timedelta.resolution 的最近倍数。
f = t2 / t3 总持续时间* t2 的间隔(3)除以间隔单位 t3 *。返回一个float对象。
t1 = t2 / f or t1 = t2 / i Delta 除以浮点数或整数。使用二分之一到四舍五入将结果四舍五入到 timedelta.resolution 的最近倍数。
t1 = t2 // it1 = t2 // t3 计算底数,其余部分(如果有)被丢弃。在第二种情况下,将返回一个整数。 (3)
t1 = t2 % t3 余数计算为timedelta对象。 (3)
q, r = divmod(t1, t2) 计算商和余数:q = t1 // t2(3)和r = t1 % t2。 q 是整数,r 是timedelta对象。
+t1 返回具有相同值的timedelta对象。 (2)
-t1 等效于timedelta(-* t1.days ,- t1.seconds ,- t1.microseconds )和 t1 * * -1. (1)(4)
abs(t) 等效于t.days >= 0时的* t ,以及t.days < 0时的- t *。 (2)
str(t) 返回格式为[D day[s], ][H]H:MM:SS[.UUUUUU]的字符串,其中 D 表示负数t的负数。 (5)
repr(t) 返回具有规范属性值的timedelta对象的字符串表示形式,以作为构造函数调用。

Notes:

>>> timedelta(hours=-5)
datetime.timedelta(days=-1, seconds=68400)
>>> print(_)
-1 day, 19:00:00

除了上面列出的操作外,timedelta对象还支持对datedatetime对象进行某些加法和减法(请参见下文)。

在版本 3.2 中进行了更改:现在支持timedelta对象的地板分割和 true 的除以另一个timedelta对象的分割,以及其余操作和divmod()函数。现在支持timedelta对象与float对象的真实除法和乘法。

支持timedelta个对象的比较,但有一些警告。

比较==!= 总是返回bool,无论所比较对象的类型如何:

>>> from datetime import timedelta
>>> delta1 = timedelta(seconds=57)
>>> delta2 = timedelta(hours=25, seconds=2)
>>> delta2 != delta1
True
>>> delta2 == 5
False

对于所有其他比较(例如<>),当将timedelta对象与不同类型的对象进行比较时,将引发TypeError

>>> delta2 > delta1
True
>>> delta2 > 5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'datetime.timedelta' and 'int'

在布尔上下文中,当且仅当timedelta对象不等于timedelta(0)时,该对象才被视为 true。

Instance methods:

请注意,对于非常长的时间间隔(在大多数平台上大于 270 年),此方法将失去微秒的精度。

3.2 版中的新Function。

使用示例:timedelta

标准化的另一个示例:

>>> # Components of another_year add up to exactly 365 days
>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> another_year = timedelta(weeks=40, days=84, hours=23,
...                          minutes=50, seconds=600)
>>> year == another_year
True
>>> year.total_seconds()
31536000.0

timedelta算法的示例:

>>> from datetime import timedelta
>>> year = timedelta(days=365)
>>> ten_years = 10 * year
>>> ten_years
datetime.timedelta(days=3650)
>>> ten_years.days // 365
10
>>> nine_years = ten_years - year
>>> nine_years
datetime.timedelta(days=3285)
>>> three_years = nine_years // 3
>>> three_years, three_years.days // 365
(datetime.timedelta(days=1095), 3)

date Objects

date对象代表理想 calendar 中的日期(年,月和日),当前公历 calendar 在两个方向上无限期扩展。

第 1 年的 1 月 1 日称为第 1 天,第 1 年的 1 月 2 日称为第 2 天,依此类推。 [2]

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

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

这等效于date.fromtimestamp(time.time())

如果时间戳不在平台 C localtime()函数支持的值范围内,则可能会引发OverflowError,而在localtime()发生故障时会引发OSError。通常将其限制为从 1970 年到 2038 年的几年。请注意,在非 POSIX 系统上,在时间戳概念中包含 leap 秒的情况下,fromtimestamp()会忽略 leap 秒。

在版本 3.3 中进行了更改:如果时间戳超出平台 C localtime()函数支持的值范围,则提高OverflowError而不是ValueError。在localtime()失败时提高OSError而不是ValueError

除非1 <= ordinal <= date.max.toordinal(),否则ValueError被提出。对于任何日期* d *,date.fromordinal(d.toordinal()) == d

>>> from datetime import date
>>> date.fromisoformat('2019-12-04')
datetime.date(2019, 12, 4)

这是date.isoformat()的逆。它仅支持格式YYYY-MM-DD

3.7 版中的新Function。

3.8 版的新Function。

Class attributes:

实例属性(只读):

Supported operations:

Operation Result
date2 = date1 + timedelta * date2 已从 date1 *中删除timedelta.days天。 (1)
date2 = date1 - timedelta 计算* date2 *这样的date2 + timedelta == date1。 (2)
timedelta = date1 - date2 (3)
date1 < date2 如果* date1 在时间上早于 date2 ,则 date1 被认为小于 date2 *。 (4)

Notes:

在布尔上下文中,所有date对象都被视为正确。

Instance methods:

Example:

>>> from datetime import date
>>> d = date(2002, 12, 31)
>>> d.replace(day=26)
datetime.date(2002, 12, 26)

小时,分钟和秒为 0,DST 标志为-1.

d.timetuple()等效于:

time.struct_time((d.year, d.month, d.day, 0, 0, 0, d.weekday(), yday, -1))

其中yday = d.toordinal() - date(d.year, 1, 1).toordinal() + 1是本年内从 1 月 1 日起1开始的天数。

ISOcalendar 是公历的一种广泛使用的变体。 [3]

ISO 年度包括 52 或 53 个整周,其中一个星期从星期一开始,在星期日结束。 ISO 年的第一周是包含星期四的一年中的第一个(格里高利历)calendar 周。这称为第 1 周,该周四的 ISO 年与其公历年相同。

例如,2004 年从星期四开始,因此 ISO 2004 年的第一周从 2003 年 12 月 29 日星期一开始,到 2004 年 1 月 4 日星期日结束:

>>> from datetime import date
>>> date(2003, 12, 29).isocalendar()
(2004, 1, 1)
>>> date(2004, 1, 4).isocalendar()
(2004, 1, 7)
>>> from datetime import date
>>> date(2002, 12, 4).isoformat()
'2002-12-04'

这是date.fromisoformat()的逆。

>>> from datetime import date
>>> date(2002, 12, 4).ctime()
'Wed Dec  4 00:00:00 2002'

d.ctime()等效于:

time.ctime(time.mktime(d.timetuple()))

在本机 C ctime()函数(time.ctime()调用但date.ctime()不调用)符合 C 标准的平台上。

使用示例:日期

计算事件天数的示例:

>>> import time
>>> from datetime import date
>>> today = date.today()
>>> today
datetime.date(2007, 12, 5)
>>> today == date.fromtimestamp(time.time())
True
>>> my_birthday = date(today.year, 6, 24)
>>> if my_birthday < today:
...     my_birthday = my_birthday.replace(year=today.year + 1)
>>> my_birthday
datetime.date(2008, 6, 24)
>>> time_to_birthday = abs(my_birthday - today)
>>> time_to_birthday.days
202

使用date的更多示例:

>>> from datetime import date
>>> d = date.fromordinal(730920) # 730920th day after 1. 1. 0001
>>> d
datetime.date(2002, 3, 11)

>>> # Methods related to formatting string output
>>> d.isoformat()
'2002-03-11'
>>> d.strftime("%d/%m/%y")
'11/03/02'
>>> d.strftime("%A %d. %B %Y")
'Monday 11. March 2002'
>>> d.ctime()
'Mon Mar 11 00:00:00 2002'
>>> 'The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day", "month")
'The day is 11, the month is March.'

>>> # Methods for to extracting 'components' under different calendars
>>> t = d.timetuple()
>>> for i in t:     
...     print(i)
2002                # year
3                   # month
11                  # day
0
0
0
0                   # weekday (0 = Monday)
70                  # 70th day in the year
-1
>>> ic = d.isocalendar()
>>> for i in ic:    
...     print(i)
2002                # ISO year
11                  # ISO week number
1                   # ISO day number ( 1 = Monday )

>>> # A date object is immutable; all operations produce a new object
>>> d.replace(year=2005)
datetime.date(2005, 3, 11)

datetime Objects

datetime对象是包含来自date对象和time对象的所有信息的单个对象。

date对象一样,datetime假定当前公历沿两个方向延伸;就像time对象一样,datetime假设每天恰好有 3600 * 24 秒。

Constructor:

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

3.6 版的新Function:添加了fold参数。

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

Equivalent to:

datetime.fromtimestamp(time.time())

另请参见now()fromtimestamp()

此方法在Function上等效于now(),但没有tz参数。

如果可选参数* tz *为None或未指定,则类似于today(),但是,如果可能的话,它提供的精度比passtime.time()时间戳获得的精度更高(例如,在提供 C gettimeofday()函数的平台上可以实现这种精度) )。

如果* tz 不是None,则它必须是tzinfo子类的实例,并且当前日期和时间将转换为 tz *的时区。

此Function优于today()utcnow()

就像now()一样,但是返回当前的 UTC 日期和时间(作为天真的datetime对象)。可以pass调用datetime.now(timezone.utc)获得已知的当前 UTC 日期时间。另请参见now()

Warning

因为许多其他datetime方法将朴素的datetime对象视为本地时间,所以最好使用可感知的日期时间来表示 UTC 时间。因此,建议使用 UTC 创建表示当前时间的对象的方法是调用datetime.now(timezone.utc)

如果* tz 不是None,则它必须是tzinfo子类的实例,并且时间戳将转换为 tz *的时区。

如果时间戳不在平台 C localtime()gmtime()函数支持的值范围内,并且OSErrorlocaltime()gmtime()失败时,则fromtimestamp()可能会引发OverflowError。通常将此限制在 1970 年到 2038 年之间。请注意,在非 POSIX 系统上,在时间戳概念中包含 leap 秒的情况下,fromtimestamp()会忽略 leap 秒,然后可能会有两个时间戳之间的差异第二个产生相同的datetime对象。此方法优于utcfromtimestamp()

在版本 3.3 中进行了更改:如果时间戳超出平台 C localtime()gmtime()函数支持的值范围,则提高OverflowError而不是ValueError。在localtime()gmtime()故障时提高OSError而不是ValueError

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

如果时间戳不在平台 C gmtime()函数支持的值范围内,则可能会引发OverflowError,而在gmtime()发生故障时会引发OSError。通常将其限制在 1970 年至 2038 年之间。

要获取可感知的datetime对象,请致电fromtimestamp()

datetime.fromtimestamp(timestamp, timezone.utc)

在符合 POSIX 的平台上,它等效于以下表达式:

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

除了后一个公式始终支持整个年份范围:介于MINYEARMAXYEAR之间(包括_)。

Warning

因为许多其他datetime方法将朴素的datetime对象视为本地时间,所以最好使用可感知的日期时间来表示 UTC 时间。因此,建议使用datetime.fromtimestamp(timestamp, tz=timezone.utc)来创建表示 UTC 中特定时间戳记的对象的方法。

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

对于任何datetime对象* d *,d == datetime.combine(d.date(), d.time(), d.tzinfo)。如果 date 是datetime对象,则将忽略其时间成分和tzinfo属性。

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

具体来说,此函数支持以下格式的字符串:

YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]

*可以匹配任何单个字符。

Caution

支持解析任意 ISO 8601 字符串-仅用作datetime.isoformat()的逆运算。第三方包dateutil中提供了Function更全的 ISO 8601 解析器dateutil.parser.isoparse

Examples:

>>> from datetime import datetime
>>> datetime.fromisoformat('2011-11-04')
datetime.datetime(2011, 11, 4, 0, 0)
>>> datetime.fromisoformat('2011-11-04T00:05:23')
datetime.datetime(2011, 11, 4, 0, 5, 23)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000)
>>> datetime.fromisoformat('2011-11-04 00:05:23.283+00:00')
datetime.datetime(2011, 11, 4, 0, 5, 23, 283000, tzinfo=datetime.timezone.utc)
>>> datetime.fromisoformat('2011-11-04T00:05:23+04:00')   
datetime.datetime(2011, 11, 4, 0, 5, 23,
    tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

3.7 版中的新Function。

3.8 版的新Function。

这等效于:

datetime(*(time.strptime(date_string, format)[0:6]))

如果time.strptime()无法解析 date_string 和格式,或者返回的值不是时间 Tuples,则引发ValueError。有关格式设置指令的完整列表,请参见strftime()和 strptime()行为

Class attributes:

实例属性(只读):

3.6 版的新Function。

Supported operations:

Operation Result
datetime2 = datetime1 + timedelta (1)
datetime2 = datetime1 - timedelta (2)
timedelta = datetime1 - datetime2 (3)
datetime1 < datetime2 比较datetimedatetime。 (4)

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

如果两者都知道并具有不同的tzinfo属性,则a-b的行为就好像首先将* a b *转换为原始 UTC 日期时间一样。结果为(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset()),除了实现永不溢出。

如果一个比较项比较幼稚而另一个比较清楚,则try进行 Sequences 比较时会引发TypeError。对于相等性比较,朴素的实例永远不会等于有意识的实例。

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

在版本 3.3 中进行了更改:有意识的天真datetime实例之间的相等比较不会引发TypeError

Note

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

Instance methods:

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

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

3.6 版的新Function:添加了fold参数。

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

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

如果self.tzinfo是* tz ,则self.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子类中覆盖默认的tzinfo.fromutc()方法,以影响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 中更改:现在可以Ellipsis* tz *。

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

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

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

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 日。根据dst()方法设置结果的tm_isdst标志:tzinfoNonedst()返回Nonetm_isdst设置为-1;否则,如果dst()返回非零值,则tm_isdst设置为1;否则tm_isdst设置为0

如果* d 知道,则pass减去d.utcoffset() d 标准化为 UTC 时间,并返回标准化时间的time.struct_timetm_isdst强制为 0.请注意,如果 d * .year 是MINYEARMAXYEAR,并且 UTC 调整溢出到年份边界,则可能会引发OverflowError

Warning

由于许多原始的datetime对象被许多datetime方法视为本地时间,因此最好使用可感知的日期时间来表示 UTC 时间;结果,使用utcfromtimetuple可能会产生误导性的结果。如果您的天真datetime代表 UTC,请使用datetime.replace(tzinfo=timezone.utc)使其知道,此时可以使用datetime.timetuple()

假定幼稚的datetime实例代表本地时间,并且此方法依赖于平台 C mktime()函数来执行转换。由于在许多平台上datetimemktime()支持更广泛的值范围,因此此方法可能在过去或将来的较长时间内提高OverflowError

对于已知的datetime个实例,返回值的计算方式为:

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

版本 3.3 中的新Function。

在版本 3.6 中进行了更改:timestamp()方法使用fold属性来消除重复间隔中的时间。

Note

没有直接从表示 UTC 时间的天真datetime实例直接获取 POSIX 时间戳的方法。如果您的应用程序使用此约定,并且系统时区未设置为 UTC,则可以pass提供tzinfo=timezone.utc获得 POSIX 时间戳:

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

或直接计算时间戳记:

timestamp = (dt - datetime(1970, 1, 1)) / timedelta(seconds=1)

如果utcoffset()不返回None,则会附加一个字符串,并给出 UTC 偏移量:

Examples:

>>> from datetime import datetime, timezone
>>> datetime(2019, 5, 18, 15, 17, 8, 132263).isoformat()
'2019-05-18T15:17:08.132263'
>>> datetime(2019, 5, 18, 15, 17, tzinfo=timezone.utc).isoformat()
'2019-05-18T15:17:00+00:00'

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

>>> from datetime import tzinfo, timedelta, datetime
>>> class TZ(tzinfo):
...     """A time zone with an arbitrary, constant -06:39 offset."""
...     def utcoffset(self, dt):
...         return timedelta(hours=-6, minutes=-39)
...
>>> datetime(2002, 12, 25, tzinfo=TZ()).isoformat(' ')
'2002-12-25 00:00:00-06:39'
>>> datetime(2009, 11, 27, microsecond=100, tzinfo=TZ()).isoformat()
'2009-11-27T00:00:00.000100-06:39'

可选参数* timespec *指定要包括的时间的其他组成部分的数量(默认为'auto')。可以是以下之一:

Note

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

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 版的新Function:添加了* timespec *参数。

>>> from datetime import datetime
>>> datetime(2002, 12, 4, 20, 30, 40).ctime()
'Wed Dec  4 20:30:40 2002'

无论 Importing 是感知还是天真,输出字符串都将包含时区信息。

d.ctime()等效于:

time.ctime(time.mktime(d.timetuple()))

在本机 C ctime()函数(time.ctime()调用但datetime.ctime()不调用)符合 C 标准的平台上。

使用示例:datetime

使用datetime对象的示例:

>>> from datetime import datetime, date, time, timezone

>>> # 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()
>>> datetime.now()   
datetime.datetime(2007, 12, 6, 16, 29, 43, 79043)   # GMT +1
>>> datetime.now(timezone.utc)   
datetime.datetime(2007, 12, 6, 15, 29, 43, 79060, tzinfo=datetime.timezone.utc)

>>> # 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 a 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子类捕获时区信息,该类使用 4 UTC 直到 1945 年,然后使用 4:30 UTC:

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):
            # An ambiguous ("imaginary") half-hour range representing
            # a 'fold' in time due to the shift from +4 to +4: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):
        # 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")

        # 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.
        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):
        # Kabul does not observe daylight saving time.
        return timedelta(0)

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

上面KabulTz的用法:

>>> 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 == dt3
True

time Objects

time对象代表一天中的(本地)时间,与任何特定的日期无关,并且可以passtzinfo对象进行调整。

如果给出了超出这些范围的参数,则引发ValueError。除* tzinfo *(默认为None)外,其他所有默认值为0

Class attributes:

实例属性(只读):

3.6 版的新Function。

time个对象支持timetime的比较,其中* a 在时间上优先于 b 时, a 被认为小于 b *。如果一个比较项比较幼稚而另一个比较清楚,则try进行 Sequences 比较时会引发TypeError。对于相等性比较,朴素的实例永远不会等于有意识的实例。

如果两个比较符都知道并且具有相同的tzinfo属性,则将忽略公共tzinfo属性,并比较基准时间。如果两个比较器都知道并且具有不同的tzinfo属性,则首先pass减去其 UTC 偏移量(从self.utcoffset()获得)来调整比较器。为了阻止混合类型比较回退到按对象地址进行的默认比较,将time对象与其他类型的对象进行比较时,除非比较是==!=,否则将引发TypeError。后一种情况分别返回FalseTrue

在版本 3.3 中进行了更改:有意识的天真time实例之间的相等比较不会引发TypeError

在布尔上下文中,time对象始终被视为 true。

在版本 3.5 中进行了更改:在 Python 3.5 之前,如果time对象表示 UTC 的午夜,则认为该对象为 false。这种行为被认为是晦涩且容易出错的,在 Python 3.5 中已被删除。有关详细信息,请参见bpo-13936

Other constructor:

HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]

Caution

支持解析任意 ISO 8601 字符串。它仅用作time.isoformat()的逆运算。

Examples:

>>> from datetime import time
>>> time.fromisoformat('04:23:01')
datetime.time(4, 23, 1)
>>> time.fromisoformat('04:23:01.000384')
datetime.time(4, 23, 1, 384)
>>> time.fromisoformat('04:23:01+04:00')
datetime.time(4, 23, 1, tzinfo=datetime.timezone(datetime.timedelta(seconds=14400)))

3.7 版中的新Function。

Instance methods:

3.6 版的新Function:添加了fold参数。

可选参数* timespec *指定要包括的时间的其他组成部分的数量(默认为'auto')。可以是以下之一:

Note

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

无效的* timespec *参数将引发ValueError

Example:

>>> from datetime import time
>>> time(hour=12, minute=34, second=56, microsecond=123456).isoformat(timespec='minutes')
'12:34'
>>> dt = time(hour=12, minute=34, second=56, microsecond=0)
>>> dt.isoformat(timespec='microseconds')
'12:34:56.000000'
>>> dt.isoformat(timespec='auto')
'12:34:56'

3.6 版的新Function:添加了* timespec *参数。

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

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

使用示例:时间

使用time对象的示例:

>>> from datetime import time, tzinfo, timedelta
>>> class TZ1(tzinfo):
...     def utcoffset(self, dt):
...         return timedelta(hours=1)
...     def dst(self, dt):
...         return timedelta(0)
...     def tzname(self,dt):
...         return "+01:00"
...     def  __repr__(self):
...         return f"{self.__class__.__name__}()"
...
>>> t = time(12, 10, 30, tzinfo=TZ1())
>>> t
datetime.time(12, 10, 30, tzinfo=TZ1())
>>> t.isoformat()
'12:10:30+01:00'
>>> t.dst()
datetime.timedelta(0)
>>> t.tzname()
'+01:00'
>>> t.strftime("%H:%M:%S %Z")
'12:10:30 +01:00'
>>> 'The {} is {:%H:%M}.'.format("time", t)
'The time is 12:10.'

tzinfo Objects

tzinfo的实例(具体子类)可以传递给datetimetime对象的构造函数。后者的对象将其属性视为本地时间,而tzinfo对象则支持显示相对于传递给它们的日期或时间对象而言,相对于 UTC 的本地时间偏移,时区名称和 DST 偏移的方法。

您需要派生一个具体的子类,并且(至少)提供所使用的datetime方法所需的标准tzinfo方法的实现。 datetime模块提供timezone,这是tzinfo的简单具体子类,它可以表示与 UTC 具有固定偏移量的时区,例如 UTC 本身或北美 EST 和 EDT。

腌制的特殊要求:tzinfo子类必须具有init()方法,该方法可以不带任何参数地进行调用,否则可以对其进行腌制,但可能不能再次取消腌制。这是一项技术要求,将来可能会放宽。

tzinfo的具体子类可能需要实现以下方法。究竟需要哪种方法取决于对已知的datetime对象的使用。如有疑问,只需实施所有这些。

这表示与 UTC 的总计偏移量;例如,如果tzinfo对象代表时区和夏令时调整,则utcoffset()应返回其总和。如果不知道 UTC 偏移量,则返回None。否则,返回的值必须是严格在-timedelta(hours=24)timedelta(hours=24)之间的timedelta对象(偏移量的大小必须小于一天)。 utcoffset()的大多数实现可能看起来像这两个之一:

return CONSTANT                 # fixed-offset class
return CONSTANT + self.dst(dt)  # daylight-aware class

如果utcoffset()不返回None,则dst()也不应返回None

默认实现utcoffset()引发NotImplementedError

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

如果 DST 无效,则返回timedelta(0)。如果 DST 有效,则将偏移量作为timedelta对象返回(有关详细信息,请参见utcoffset())。请注意,DST 偏移(如果适用)已经添加到utcoffset()返回的 UTC 偏移中,因此除非您有兴趣单独获取 DST 信息,否则无需咨询dst()。例如,datetime.timetuple()调用其tzinfo属性的dst()方法来确定应如何设置tm_isdst标志,并且tzinfo.fromutc()调用dst()以解决跨时区的 DST 变化。

从这个意义上讲,同时模拟标准时间和夏令时的tzinfo子类的实例* tz *必须保持一致:

tz.utcoffset(dt) - tz.dst(dt)

对于带有dt.tzinfo == tz的每个datetime * dt *,必须返回相同的结果。对于同等的tzinfo子类,此表达式将产生时区的“标准偏移量”,该偏移量不取决于日期或时间,而仅取决于地理位置。 datetime.astimezone()的实现依赖于此,但是无法检测到违例;确保它是程序员的责任。如果tzinfo子类不能保证这一点,则它可以覆盖tzinfo.fromutc()的默认实现以与astimezone()一起正常工作。

dst()的大多数实现可能看起来像这两个之一:

def dst(self, dt):
    # a fixed-offset class:  doesn't account for DST
    return timedelta(0)

or:

def dst(self, dt):
    # Code to set dston and dstoff to the time zone's DST
    # transition times based on the input dt.year, and expressed
    # in standard local time.

    if dston <= dt.replace(tzinfo=None) < dstoff:
        return timedelta(hours=1)
    else:
        return timedelta(0)

默认实现dst()引发NotImplementedError

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

默认实现tzname()引发NotImplementedError

响应它们的相同名称的方法,这些方法由datetimetime对象调用。 datetime对象将自身作为参数传递,而time对象将None作为参数传递。因此,应准备tzinfo子类的方法以接受None或类datetime的* dt *参数。

传递None时,由类设计者决定最佳响应。例如,如果类希望说时间对象不参与tzinfo协议,则返回None是适当的。 utcoffset(None)返回标准 UTC 偏移量可能更有用,因为没有其他约定可以发现标准偏移量。

当响应datetime对象而传递datetime对象时,dt.tzinfo与* self 是同Pair象。 tzinfo方法可以依赖于此,除非用户代码直接调用tzinfo方法。目的是tzinfo方法将 dt *解释为本地时间,而不必担心其他时区的对象。

子类可能希望重写另一个tzinfo方法:

大多数tzinfo子类应该能够继承默认的fromutc()实现,而不会出现问题。它具有足够的能力来处理固定偏移的时区,并且时区同时考虑了标准时间和夏令时,即使 DST 转换时间在不同年份有所不同,后者也是如此。默认fromutc()实现可能无法在所有情况下正确处理的时区示例是标准偏移量(与 UTC 的距离)取决于所经过的特定日期和时间的情况,这可能是出于政治原因。 astimezone()fromutc()的默认实现可能不会产生您想要的结果,如果结果是跨越标准偏移量的时间之一。

针对错误情况跳过代码,默认的fromutc()实现类似于:

def fromutc(self, dt):
    # raise ValueError error if dt.tzinfo is not self
    dtoff = dt.utcoffset()
    dtdst = dt.dst()
    # raise ValueError if dtoff is None or dtdst is None
    delta = dtoff - dtdst  # this is self's standard offset
    if delta:
        dt += delta   # convert to standard local time
        dtdst = dt.dst()
        # raise ValueError if dtdst is None
    if dtdst:
        return dt + dtdst
    else:
        return dt

在以下tzinfo_examples.py文件中,有tzinfo类的一些示例:

from datetime import tzinfo, timedelta, datetime

ZERO = timedelta(0)
HOUR = timedelta(hours=1)
SECOND = timedelta(seconds=1)

# A class capturing the platform's idea of local time.
# (May result in wrong values on historical times in
#  timezones where UTC offset and/or the DST rules had
#  changed in the past.)
import time as _time

STDOFFSET = timedelta(seconds = -_time.timezone)
if _time.daylight:
    DSTOFFSET = timedelta(seconds = -_time.altzone)
else:
    DSTOFFSET = STDOFFSET

DSTDIFF = DSTOFFSET - STDOFFSET

class LocalTimezone(tzinfo):

    def fromutc(self, dt):
        assert dt.tzinfo is self
        stamp = (dt - datetime(1970, 1, 1, tzinfo=self)) // SECOND
        args = _time.localtime(stamp)[:6]
        dst_diff = DSTDIFF // SECOND
        # Detect fold
        fold = (args == _time.localtime(stamp - dst_diff))
        return datetime(*args, microsecond=dt.microsecond,
                        tzinfo=self, fold=fold)

    def utcoffset(self, dt):
        if self._isdst(dt):
            return DSTOFFSET
        else:
            return STDOFFSET

    def dst(self, dt):
        if self._isdst(dt):
            return DSTDIFF
        else:
            return ZERO

    def tzname(self, dt):
        return _time.tzname[self._isdst(dt)]

    def _isdst(self, dt):
        tt = (dt.year, dt.month, dt.day,
              dt.hour, dt.minute, dt.second,
              dt.weekday(), 0, 0)
        stamp = _time.mktime(tt)
        tt = _time.localtime(stamp)
        return tt.tm_isdst > 0

Local = LocalTimezone()

# A complete implementation of current DST rules for major US time zones.

def first_sunday_on_or_after(dt):
    days_to_go = 6 - dt.weekday()
    if days_to_go:
        dt += timedelta(days_to_go)
    return dt

# US DST Rules
#
# This is a simplified (i.e., wrong for a few cases) set of rules for US
# DST start and end times. For a complete and up-to-date set of DST rules
# and timezone definitions, visit the Olson Database (or try pytz):
# http://www.twinsun.com/tz/tz-link.htm
# http://sourceforge.net/projects/pytz/ (might not be up-to-date)
#
# In the US, since 2007, DST starts at 2am (standard time) on the second
# Sunday in March, which is the first Sunday on or after Mar 8.
DSTSTART_2007 = datetime(1, 3, 8, 2)
# and ends at 2am (DST time) on the first Sunday of Nov.
DSTEND_2007 = datetime(1, 11, 1, 2)
# From 1987 to 2006, DST used to start at 2am (standard time) on the first
# Sunday in April and to end at 2am (DST time) on the last
# Sunday of October, which is the first Sunday on or after Oct 25.
DSTSTART_1987_2006 = datetime(1, 4, 1, 2)
DSTEND_1987_2006 = datetime(1, 10, 25, 2)
# From 1967 to 1986, DST used to start at 2am (standard time) on the last
# Sunday in April (the one on or after April 24) and to end at 2am (DST time)
# on the last Sunday of October, which is the first Sunday
# on or after Oct 25.
DSTSTART_1967_1986 = datetime(1, 4, 24, 2)
DSTEND_1967_1986 = DSTEND_1987_2006

def us_dst_range(year):
    # Find start and end times for US DST. For years before 1967, return
    # start = end for no DST.
    if 2006 < year:
        dststart, dstend = DSTSTART_2007, DSTEND_2007
    elif 1986 < year < 2007:
        dststart, dstend = DSTSTART_1987_2006, DSTEND_1987_2006
    elif 1966 < year < 1987:
        dststart, dstend = DSTSTART_1967_1986, DSTEND_1967_1986
    else:
        return (datetime(year, 1, 1), ) * 2

    start = first_sunday_on_or_after(dststart.replace(year=year))
    end = first_sunday_on_or_after(dstend.replace(year=year))
    return start, end

class USTimeZone(tzinfo):

    def __init__(self, hours, reprname, stdname, dstname):
        self.stdoffset = timedelta(hours=hours)
        self.reprname = reprname
        self.stdname = stdname
        self.dstname = dstname

    def __repr__(self):
        return self.reprname

    def tzname(self, dt):
        if self.dst(dt):
            return self.dstname
        else:
            return self.stdname

    def utcoffset(self, dt):
        return self.stdoffset + self.dst(dt)

    def dst(self, dt):
        if dt is None or dt.tzinfo is None:
            # An exception may be sensible here, in one or both cases.
            # It depends on how you want to treat them.  The default
            # fromutc() implementation (called by the default astimezone()
            # implementation) passes a datetime with dt.tzinfo is self.
            return ZERO
        assert dt.tzinfo is self
        start, end = us_dst_range(dt.year)
        # Can't compare naive to aware objects, so strip the timezone from
        # dt first.
        dt = dt.replace(tzinfo=None)
        if start + HOUR <= dt < end - HOUR:
            # DST is in effect.
            return HOUR
        if end - HOUR <= dt < end:
            # Fold (an ambiguous hour): use dt.fold to disambiguate.
            return ZERO if dt.fold else HOUR
        if start <= dt < start + HOUR:
            # Gap (a non-existent hour): reverse the fold rule.
            return HOUR if dt.fold else ZERO
        # DST is off.
        return ZERO

    def fromutc(self, dt):
        assert dt.tzinfo is self
        start, end = us_dst_range(dt.year)
        start = start.replace(tzinfo=self)
        end = end.replace(tzinfo=self)
        std_time = dt + self.stdoffset
        dst_time = std_time + HOUR
        if end <= dst_time < end + HOUR:
            # Repeated hour
            return std_time.replace(fold=1)
        if std_time < start or dst_time >= end:
            # Standard time
            return std_time
        if start <= std_time < end - HOUR:
            # Daylight saving time
            return dst_time

Eastern  = USTimeZone(-5, "Eastern",  "EST", "EDT")
Central  = USTimeZone(-6, "Central",  "CST", "CDT")
Mountain = USTimeZone(-7, "Mountain", "MST", "MDT")
Pacific  = USTimeZone(-8, "Pacific",  "PST", "PDT")

请注意,在tzinfo子类中,每年 DST 过渡点的标准时间和夏时制都有不可避免的细微之处。具体而言,请考虑美国东部(UTC -0500),EDT 在 3 月的第二个星期日的 1:59(EST)之后的分钟开始,并在 11 月的第一个星期日的 1:59(EDT)之后的分钟结束:

UTC   3:MM  4:MM  5:MM  6:MM  7:MM  8:MM
  EST  22:MM 23:MM  0:MM  1:MM  2:MM  3:MM
  EDT  23:MM  0:MM  1:MM  2:MM  3:MM  4:MM

start  22:MM 23:MM  0:MM  1:MM  3:MM  4:MM

  end  23:MM  0:MM  1:MM  1:MM  2:MM  3:MM

DST 开始时(“开始”行),本地壁钟从 1:59 跳到 3:00.格式为 2:MM 的有效时间在该天实际上没有意义,因此astimezone(Eastern)不会在 DST 开始的那一天与hour == 2传递结果。例如,在 2016 年 Spring 向前过渡中,我们得到:

>>> from datetime import datetime, timezone
>>> from tzinfo_examples import HOUR, Eastern
>>> u0 = datetime(2016, 3, 13, 5, tzinfo=timezone.utc)
>>> for i in range(4):
...     u = u0 + i*HOUR
...     t = u.astimezone(Eastern)
...     print(u.time(), 'UTC =', t.time(), t.tzname())
...
05:00:00 UTC = 00:00:00 EST
06:00:00 UTC = 01:00:00 EST
07:00:00 UTC = 03:00:00 EDT
08:00:00 UTC = 04:00:00 EDT

当 DST 结束(“结束”行)时,可能会出现一个更严重的问题:在当地的墙上时间,不能明确地拼写一个小时:夏令时的最后一个小时。在东部,白天的时间是 5:MM UTC。当地壁钟再次从 1:59(夏令时)跳回到 1:00(标准时间)。 1:MM 形式的当地时间是模棱两可的。 astimezone()pass将两个相邻的 UTC 小时 Map 到同一本地时间来模仿本地时钟的行为。在东部示例中,格式为 5:MM 和 6:MM 的 UTC 时间在转换为东部时都 Map 为 1:MM,但是更早的时间将fold属性设置为 0,而更晚的时间将其设置为 1.例如,在 2016 年的后备过渡中,我们得到:

>>> u0 = datetime(2016, 11, 6, 4, tzinfo=timezone.utc)
>>> for i in range(4):
...     u = u0 + i*HOUR
...     t = u.astimezone(Eastern)
...     print(u.time(), 'UTC =', t.time(), t.tzname(), t.fold)
...
04:00:00 UTC = 00:00:00 EDT 0
05:00:00 UTC = 01:00:00 EDT 0
06:00:00 UTC = 01:00:00 EST 1
07:00:00 UTC = 02:00:00 EST 0

请注意,在比较中,仅相差fold属性值的datetime实例被视为相等。

无法忍受时间不确定性的应用程序应显式检查fold属性的值,或避免使用混合tzinfo子类;使用timezone或任何其他固定偏移tzinfo子类(例如仅表示 EST(固定偏移-5 小时)或仅 EDT(固定偏移-4 小时)的类)时,没有歧义。

See also

  • dateutil.tz 库将 IANA 时区数据库*(也称为 Olson 数据库)引入了 Python,建议使用它。
  • IANA 时区数据库

  • 时区数据库(通常称为 tz,tzdata 或 zoneinfo)包含代表 Global 许多代表性位置的本地时间历史的代码和数据。它会定期更新,以反映政治机构对时区边界,UTC 偏移量和夏令时规则所做的更改。

timezone Objects

timezone类是tzinfo的子类,其每个实例代表一个时区,该时区由与 UTC 的固定偏移量定义。

此类对象不能用于表示在一年中的不同日期或对民用时间进行过历史更改的位置中的时区信息。

3.2 版中的新Function。

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

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

如果构造函数中未提供* name ,则由tzname(dt)返回的名称是根据offset的值生成的,如下所示。如果 offset *为timedelta(0),则名称为“ UTC”,否则为格式为UTC±HH:MM的字符串,其中±是offset的符号,HH 和 MM 分别是offset.hoursoffset.minutes的两位数字。

在版本 3.6 中更改:从offset=timedelta(0)生成的名称现在是普通的'UTC',而不是'UTC+00:00'

Class attributes:

strftime()和 strptime()行为

datedatetimetime对象均支持strftime(format)方法,以在显式格式字符串的控制下创建表示时间的字符串。

相反,datetime.strptime()类方法从表示日期和时间的字符串以及相应的格式字符串中创建datetime对象。

下表提供了strftime()strptime()的高层比较:

strftime strptime
Usage 根据给定的格式将对象转换为字符串 将字符串解析为具有相应格式的datetime对象
方法类型 Instance method Class method
Method of date; datetime; time datetime
Signature strftime(format) strptime(date_string, format)

strftime()和 strptime()格式代码

以下是 1989 C 标准要求的所有格式代码的列表,并且这些格式代码在所有使用标准 C 实现的平台上均可工作。

Directive Meaning Example Notes
%a 工作日为语言环境的缩写名称。 周日,周一,…,周六(en_US);

因此,Mo,...,Sa(de_DE)
(1)
%A 工作日为语言环境的全名。 星期日,星期一,…,星期六(zh_CN);
桑塔格,蒙塔格,…,萨姆斯塔格(de_DE)
(1)
%w 工作日作为十进制数字,其中 0 是星期日,6 是星期六。 0,1,…,6
%d 每月的一天,以零填充的十进制数。 01、02,…,31 (9)
%b 月份为语言环境的缩写名称。 1 月,2 月,…,12 月(zh_CN);
一月,二月,…,迪斯(de_DE)
(1)
%B 月份为语言环境的全名。 1 月,2 月,…,12 月(en_US);
Januar,Februar,...,Dezember(de_DE)
(1)
%m 月份为零填充的十进制数字。 01、02,…,12 (9)
%y 无世纪的年份作为补零的十进制数字。 00,01,…,99 (9)
%Y 以世纪作为十进制数字的年份。 0001,0002,…,2013,2014,…,9998,9999 (2)
%H 小时(24 小时制),为零填充的十进制数字。 00、01,…,23 (9)
%I 小时(12 小时制),为零填充的十进制数字。 01、02,…,12 (9)
%p 相当于 AM 或 PM 的语言环境。 AM,PM(en_US);
上午,下午(de_DE)
(1),(3)
%M 分钟,为零填充的十进制数字。 00,01,…,59 (9)
%S 第二个为零填充的十进制数字。 00,01,…,59 (4),(9)
%f 微秒为十进制数字,左侧为零。 000000,000001,…,999999 (5)
%z UTC 偏移量,格式为±HHMM[SS[.ffffff]](如果对象是天真对象,则为空字符串)。 (空),0000,-0400、1030、063415,-030712.345216 (6)
%Z 时区名称(如果对象是天真对象,则为空字符串)。 (空),UTC,EST,CST
%j 一年中的一天,用零填充的十进制数字。 001,002,…,366 (9)
%U 一年中的周号(星期日为一周的第一天),为零填充的十进制数。第一个星期日之前的新的一年中的所有天都被视为在第 0 周。 00,01,…,53 (7),(9)
%W 一年中的星期几(星期一为星期几),以十进制数表示。第一个星期一之前的新的一年中的所有天都被视为在第 0 周。 00,01,…,53 (7),(9)
%c 语言环境的适当日期和时间表示形式。 1988 年 8 月 16 日,星期二,21:30:00(en_US);
Di 16 Aug 21:30:00 1988(de_DE)
(1)
%x 区域设置的适当日期表示形式。 08/16/88(无);
08/16/1988 (en_US);
16.08.1988 (de_DE)
(1)
%X 语言环境的适当时间表示形式。 21:30:00(en_US);
21:30:00 (de_DE)
(1)
%% Literals'%'字符。

为了方便起见,还包含了 C89 标准不需要的其他一些指令。这些参数都对应于 ISO 8601 日期值。

Directive Meaning Example Notes
%G ISO 8601 年份,以世纪表示包含 ISO 周(%V)较大部分的年份。 0001, 0002, …, 2013, 2014, …, 9998, 9999 (8)
%u ISO 8601 工作日为十进制数字,其中 1 为星期一。 1, 2, …, 7
%V ISO 8601 周为十进制数字,周一为一周的第一天。第 01 周是包含 1 月 4 日的一周。 01, 02, …, 53 (8), (9)

当与strftime()方法一起使用时,可能并非在所有平台上都可用。 ISO 8601 年和 ISO 8601 周指令与上面的年和周编号指令不可互换。使用不完整或不明确的 ISO 8601 指令调用strptime()将引发ValueError

在不同平台上,支持的全部格式代码集会有所不同,因为 Python 会调用平台 C 库的strftime()函数,并且平台版本很常见。要查看平台所支持的全套格式代码,请查阅* strftime(3) *文档。

3.6 版中的新Function:添加了%G%u%V

Technical Detail

从广义上讲,d.strftime(fmt)的行为类似于time模块的time.strftime(fmt, d.timetuple()),尽管并非所有对象都支持timetuple()方法。

对于datetime.strptime()类方法,默认值为1900-01-01T00:00:00.000:格式字符串中未指定的任何组件都将从默认值中提取。 [4]

使用datetime.strptime(date_string, format)等效于:

datetime(*(time.strptime(date_string, format)[0:6]))

格式包含datetime.strptime支持但被time.strptime丢弃的亚秒分量或时区偏移信息时除外。

对于time个对象,不应使用年,月和日的格式代码,因为time个对象没有此类值。如果仍然使用它们,则用1900代替年份,用1代替月份和日期。

对于date个对象,不应使用小时,分钟,秒和微秒的格式代码,因为date个对象没有这样的值。如果仍然使用它们,则用0代替它们。

出于同样的原因,对包含无法在当前语言环境的字符集中表示的 Unicode 代码点的格式字符串的处理也取决于平台。在某些平台上,此类代码点会保留在输出中,而在其他平台上,strftime可能会引发UnicodeError或返回空字符串。

Notes:

在版本 3.2 中更改:在以前的版本中,strftime()方法仅限于> = 1900 年。

在版本 3.3 中进行了更改:在版本 3.2 中,strftime()方法仅限于> = 1000 的年份。

对于有意识的对象:

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

在版本 3.7 中进行了更改:当将%z指令提供给strptime()方法时,UTC 偏移量可以使用冒号作为小时,分钟和秒之间的分隔符。例如,'+01:00:00'将被解析为一个小时的偏移量。另外,提供'Z''+00:00'相同。

在版本 3.2 中更改:将%z指令提供给strptime()方法时,将生成一个感知的datetime对象。结果的tzinfo将设置为timezone实例。

Footnotes

首页