datetime
--- 基本的日期和时间类型¶
源代码: Lib/datetime.py
datetime
模块提供用于处理日期和时间的类。
在支持日期时间数学运算的同时,实现的关注点更着重于如何能够更有效地解析其属性用于格式化输出和数据操作。
感知型对象和简单型对象¶
日期和时间对象可以分为“感知型”或“简单型”两类。
充分掌握应用性算法和政治性时间调整信息例如时区和夏令时的情况下,一个 感知型 对象就能相对于其他感知型对象来精确定位自身时间点。 感知型对象是用来表示一个没有解释空间的固定时间点。 1
简单型 对象没有包含足够多的信息来无歧义地相对于其他 date/time 对象来定位自身时间点。 不论一个简单型对象所代表的是世界标准时间(UTC)、当地时间还是某个其他时区的时间完全取决于具体程序,就像一个特定数字所代表的是米、英里还是质量完全取决于具体程序一样。 简单型对象更易于理解和使用,代价则是忽略了某些现实性考量。
对于要求感知型对象的应用,datetime
和 time
对象具有一个可选的时区信息属性 tzinfo
,它可被设为抽象类 tzinfo
的子类的一个实例。 这些 tzinfo
对象会捕获与 UTC 时间的差值、时区名称以及夏令时是否生效等信息。
datetime
模块只提供了一个具体的 tzinfo
类,即 timezone
类。 timezone
类可以表示具有相对于 UTC 的固定时差的简单时区,例如 UTC 本身或北美的 EST 和 EDT 时区等。 支持时间的详细程度取决于具体的应用。 世界各地的时间调整规则往往是政治性多于合理性,经常会发生变化,除了 UTC 之外并没有一个能适合所有应用的标准。
有效的类型¶
-
class
datetime.
time
一个独立于任何特定日期的理想化时间,它假设每一天都恰好等于 24*60*60 秒。 (这里没有“闰秒”的概念。) 包含属性:
hour
,minute
,second
,microsecond
和tzinfo
。
-
class
datetime.
datetime
日期和时间的结合。属性:
year
,month
,day
,hour
,minute
,second
,microsecond
, andtzinfo
.
-
class
datetime.
timezone
一个实现了
tzinfo
抽象基类的子类,用于表示相对于 世界标准时间(UTC)的偏移量。3.2 新版功能.
这些类型的对象都是不可变的。
子类关系
object
timedelta
tzinfo
timezone
time
date
datetime
timedelta
类对象¶
timedelta
对象表示两个 date 或者 time 的时间间隔。
-
class
datetime.
timedelta
(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)¶ 所有参数都是可选的并且默认为
0
。 这些参数可以是整数或者浮点数,也可以是正数或者负数。只有 days, seconds 和 microseconds 会存储在内部。 参数单位的换算规则如下:
1毫秒会转换成1000微秒。
1分钟会转换成60秒。
1小时会转换成3600秒。
1星期会转换成7天。
并且 days, seconds, microseconds 会经标准化处理以保证表达方式的唯一性,即:
0 <= microseconds < 1000000
0 <= seconds < 3600*24
(一天的秒数)-999999999 <= days <= 999999999
下面的例子演示了如何对 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)
在有任何参数为浮点型并且 microseconds 值为小数的情况下,从所有参数中余下的微秒数将被合并,并使用四舍五入偶不入奇的规则将总计值舍入到最接近的整数微秒值。 如果没有任何参数为浮点型的情况下,则转换和标准化过程将是完全精确的(不会丢失信息)。
如果标准化后的 days 数值超过了指定范围,将会抛出
OverflowError
异常。请注意对负数值进行标准化的结果可能会令人感到惊讶。 例如:
>>> from datetime import timedelta >>> d = timedelta(microseconds=-1) >>> (d.days, d.seconds, d.microseconds) (-1, 86399, 999999)
类属性:
-
timedelta.
max
¶ The most positive
timedelta
object,timedelta(days=999999999, hours=23, minutes=59, seconds=59, microseconds=999999)
.
需要注意的是,因为标准化的缘故,timedelta.max
> -timedelta.min
,-timedelta.max
不可以表示一个 timedelta
类对象。
实例属性(只读):
属性 |
值 |
---|---|
|
-999999999 至 999999999 ,含999999999 |
|
0 至 86399,包含86399 |
|
0 至 999999,包含999999 |
支持的运算:
运算 |
结果 |
---|---|
|
t2 和 t3 的和。 运算后 t1-t2 == t3 and t1-t3 == t2 必为真值。(1) |
|
t2 减 t3 的差。 运算后 t1 == t2 - t3 and t2 == t1 + t3 必为真值。 (1)(6) |
|
乘以一个整数。运算后假如 |
In general, t1 * i == t1 * (i-1) + t1 is true. (1) |
|
|
乘以一个浮点数,结果会被舍入到 timedelta 最接近的整数倍。 精度使用四舍五偶入奇不入规则。 |
|
总时间 t2 除以间隔单位 t3 (3)。 返回一个 |
|
除以一个浮点数或整数。 结果会被舍入到 timedelta 最接近的整数倍。 精度使用四舍五偶入奇不入规则。 |
|
计算底数,其余部分(如果有)将被丢弃。在第二种情况下,将返回整数。 (3) |
|
余数为一个 |
|
通过 : |
|
返回一个相同数值的 |
|
等价于 |
|
当 |
|
返回一个形如 |
|
返回一个 |
注释:
结果正确,但可能会溢出。
结果正确,不会溢出。
除以0将会抛出异常
ZeroDivisionError
。-timedelta.max 不是一个
timedelta
类对象。timedelta
对象的字符串表示形式类似于其内部表示形式被规范化。对于负时间增量,这会导致一些不寻常的结果。例如:>>> timedelta(hours=-5) datetime.timedelta(days=-1, seconds=68400) >>> print(_) -1 day, 19:00:00
表达式
t2 - t3
通常与t2 + (-t3)
是等价的,除非 t3 等于timedelta.max
; 在这种情况下前者会返回结果,而后者则会溢出。
除了上面列举的操作以外,timedelta
对象还支持与 date
和 datetime
对象进行特定的相加和相减运算(见下文)。
在 3.2 版更改: 现在已支持 timedelta
对象与另一个 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)
时则会被视为真值。
实例方法:
-
timedelta.
total_seconds
()¶ 返回时间间隔包含了多少秒。造价于
td / timedelta(seconds=1)
。对于其它单位可以直接使用除法的形式 (例如td / timedelta(microseconds=1)
)。需要注意的是,时间间隔较大时,这个方法的结果中的微秒将会失真(大多数平台上大于270年视为一个较大的时间间隔)。
3.2 新版功能.
class: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
对象¶
date
对象代表一个理想化历法中的日期(年、月和日),即当今的格列高利历向前后两个方向无限延伸。
公元 1 年 1 月 1日是第 1 日,公元 1 年 1 月 2 日是第 2 日,依此类推。 2
-
class
datetime.
date
(year, month, day)¶ 所有参数都是必要的。 参数必须是在下面范围内的整数:
MINYEAR <= year <= MAXYEAR
1 <= month <= 12
1 <= 日期 <= 给定年月对应的天数
如果参数不在这些范围内,则抛出
ValueError
异常。
其它构造器,所有的类方法:
-
classmethod
date.
today
()¶ 返回当前的本地日期。
这等价于
date.fromtimestamp(time.time())
。
-
classmethod
date.
fromtimestamp
(timestamp)¶ 返回对应于 POSIX 时间戳的当地时间,例如
time.time()
返回的就是时间戳。这可能引发
OverflowError
,如果时间戳数值超出所在平台 Clocaltime()
函数的支持范围的话,并且会在localtime()
出错时引发OSError
。 通常该数值会被限制在 1970 年至 2038 年之间。 请注意在时间戳概念包含闰秒的非 POSIX 系统上,闰秒会被fromtimestamp()
所忽略。在 3.3 版更改: 引发
OverflowError
而不是ValueError
,如果时间戳数值超出所在平台 Clocaltime()
函数的支持范围的话,并会在localtime()
出错时引发OSError
而不是ValueError
。
-
classmethod
date.
fromordinal
(ordinal)¶ 返回对应于预期格列高利历序号的日期,其中公元 1 年 1 月 1 晶的序号为 1。
除非
1 <= ordinal <= date.max.toordinal()
否则会引发ValueError
。对于任意日期 d,date.fromordinal(d.toordinal()) == d
。
-
classmethod
date.
fromisoformat
(date_string)¶ 返回一个对应于以
YYYY-MM-DD
格式给出的 date_string 的date
对象:>>> from datetime import date >>> date.fromisoformat('2019-12-04') datetime.date(2019, 12, 4)
这是
date.isoformat()
的逆操作。 它只支持YYYY-MM-DD
格式。3.7 新版功能.
-
classmethod
date.
fromisocalendar
(year, week, day)¶ 返回指定 year, week 和 day 所对应 ISO 历法日期的
date
。 这是函数date.isocalendar()
的逆操作。3.8 新版功能.
类属性:
-
date.
min
¶ 最小的日期
date(MINYEAR, 1, 1)
。
-
date.
max
¶ 最大的日期 ,
date(MAXYEAR, 12, 31)
。
-
date.
resolution
¶ 两个日期对象的最小间隔,
timedelta(days=1)
。
实例属性(只读):
-
date.
month
¶ 1 至 12(含)
-
date.
day
¶ 返回1到指定年月的天数间的数字。
支持的运算:
运算 |
结果 |
---|---|
|
date2 等于从 date1 减去 |
|
计算 date2 的值使得 |
|
(3) |
|
如果 date1 的时间在 date2 之前则认为 date1 小于 date2 。 (4) |
注释:
如果
timedelta.days > 0
则 date2 将在时间线上前进,如果timedelta.days < 0
则将后退。 操作完成后date2 - date1 == timedelta.days
。timedelta.seconds
和timedelta.microseconds
会被忽略。 如果date2.year
将小于MINYEAR
或大于MAXYEAR
则会引发OverflowError
。timedelta.seconds
和timedelta.microseconds
会被忽略。此值完全精确且不会溢出。 操作完成后 timedelta.seconds 和 timedelta.microseconds 均为 0,并且 date2 + timedelta == date1。
换句话说,当且仅当
date1.toordinal() < date2.toordinal()
时date1 < date2
。 日期比较会引发TypeError
,如果比较目标不为date
对象的话。 不过也可能会返回NotImplemented
,如果比较目标具有timetuple()
属性的话。 这个钩子给予其他日期对象类型实现混合类型比较的机会。 否则,当date
对象与不同类型的对象比较时将会引发TypeError
,除非是==
或!=
比较。 后两种情况将分别返回False
或True
。
在布尔运算中,所有 date
对象都会被视为真值。
实例方法:
-
date.
replace
(year=self.year, month=self.month, day=self.day)¶ 返回一个具有同样值的日期,除非通过任何关键字参数给出了某些形参的新值。
示例:
>>> from datetime import date >>> d = date(2002, 12, 31) >>> d.replace(day=26) datetime.date(2002, 12, 26)
-
date.
timetuple
()¶ 返回一个
time.struct_time
,即time.localtime()
所返回的类型。hours, minutes 和 seconds 值均为 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
。
-
date.
toordinal
()¶ 返回日期的预期格列高利历序号,其中公元 1 年 1 月 1 日的序号为 1。 对于任意
date
对象 d,date.fromordinal(d.toordinal()) == d
。
-
date.
weekday
()¶ 返回一个整数代表星期几,星期一为0,星期天为6。例如,
date(2002, 12, 4).weekday() == 2
,表示的是星期三。参阅isoweekday()
。
-
date.
isoweekday
()¶ 返回一个整数代表星期几,星期一为1,星期天为7。例如:
date(2002, 12, 4).isoweekday() == 3
,表示星期三。参见weekday()
,isocalendar()
。
-
date.
isocalendar
()¶ 返回一个三元元组,(ISO year, ISO week number, ISO weekday) 。
ISO 历法是一种被广泛使用的格列高利历。 3
ISO 年由 52 或 53 个完整星期构成,每个星期开始于星期一结束于星期日。 一个 ISO 年的第一个星期就是(格列高利)历法的一年中第一个包含星期四的星期。 这被称为 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)
-
date.
isoformat
()¶ 返回一个以 ISO 8601 格式
YYYY-MM-DD
来表示日期的字符串:>>> from datetime import date >>> date(2002, 12, 4).isoformat() '2002-12-04'
这是
date.fromisoformat()
的逆操作。
-
date.
__str__
()¶ 对于日期对象 d,
str(d)
等价于d.isoformat()
。
-
date.
ctime
()¶ 返回一个表示日期的字符串:
>>> 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 标准的平台上。
-
date.
strftime
(format)¶ 返回一个由显式格式字符串所指明的代表日期的字符串。 表示时、分或秒的格式代码值将为 0。 要获取格式指令的完整列表请参阅 strftime() 和 strptime() 的行为。
-
date.
__format__
(format)¶ 与
date.strftime()
相同。 此方法使得为date
对象指定以 格式化字符串字面值 表示的格式化字符串以及使用str.format()
进行格式化成为可能。 要获取格式指令的完整列表,请参阅 strftime() 和 strptime() 的行为。
class:date 用法示例¶
计算距离特定事件天数的例子:
>>> 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
对象¶
datetime
对象是包含来自 date
对象和 time
对象的所有信息的单一对象。
与 date
对象一样,datetime
假定当前的格列高利历向前后两个方向无限延伸;与 time
对象一样,datetime
假定每一天恰好有 3600*24 秒。
构造器 :
-
class
datetime.
datetime
(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)¶ year, month 和 day 参数是必须的。 tzinfo 可以是
None
或者是一个tzinfo
子类的实例。 其余的参数必须是在下面范围内的整数:MINYEAR <= year <= MAXYEAR
,1 <= month <= 12
,1 <= day <= 指定年月的天数
,0 <= hour < 24
,0 <= minute < 60
,0 <= second < 60
,0 <= microsecond < 1000000
,fold in [0, 1]
.
如果参数不在这些范围内,则抛出
ValueError
异常。3.6 新版功能: 增加了
fold
参数。
其它构造器,所有的类方法:
-
classmethod
datetime.
today
()¶ 返回表示当前地方时的 datetime 对象,其中
tzinfo
为None
。等价于:
datetime.fromtimestamp(time.time())
另请参阅
now()
,fromtimestamp()
。此方法的功能等价于
now()
,但是不带tz
形参。
-
classmethod
datetime.
now
(tz=None)¶ 返回表示当前地方时的 date 和 time 对象。
如果可选参数 tz 为
None
或未指定,这就类似于today()
,但该方法会在可能的情况下提供比通过time.time()
时间戳所获时间值更高的精度(例如,在提供了 Cgettimeofday()
函数的平台上就可以做到这一点)。如果 tz 不为
None
,它必须是tzinfo
子类的一个实例,并且当前日期和时间将被转换到 tz 时区。
-
classmethod
datetime.
utcnow
()¶ 返回表示当前 UTC 时间的 date 和 time,其中
tzinfo
为None
。这类似于
now()
,但返回的是当前 UTC 日期和时间,类型为简单型datetime
对象。 感知型的当前 UTC 日期时间可通过调用datetime.now(timezone.utc)
来获得。 另请参阅now()
。警告
由于简单型
datetime
对象会被许多datetime
方法当作本地时间来处理,最好是使用感知型日期时间对象来表示 UTC 时间。 因此,创建表示当前 UTC 时间的对象的推荐方式是通过调用datetime.now(timezone.utc)
。
-
classmethod
datetime.
fromtimestamp
(timestamp, tz=None)¶ 返回对应于 POSIX 时间戳例如
time.time()
的返回值的本地日期和时间。 如果可选参数 tz 为None
或未指定,时间戳会被转换为所在平台的本地日期和时间,返回的datetime
对象将为天真型。如果 tz 不为
None
,它必须是tzinfo
子类的一个实例,并且时间戳将被转换到 tz 指定的时区。fromtimestamp()
可能会引发OverflowError
,如果时间戳数值超出所在平台 Clocaltime()
或gmtime()
函数的支持范围的话,并会在localtime()
或gmtime()
报错时引发OSError
。 通常该数值会被限制在 1970 年至 2038 年之间。 请注意在时间戳概念包含闰秒的非 POSIX 系统上,闰秒会被fromtimestamp()
所忽略,结果可能导致两个相差一秒的时间戳产生相同的datetime
对象。 相比utcfromtimestamp()
更推荐使用此方法。在 3.3 版更改: 引发
OverflowError
而不是ValueError
,如果时间戳数值超出所在平台 Clocaltime()
或gmtime()
函数的支持范围的话。 并会在localtime()
或gmtime()
出错时引发OSError
而不是ValueError
。在 3.6 版更改:
fromtimestamp()
可能返回fold
值设为 1 的实例。
-
classmethod
datetime.
utcfromtimestamp
(timestamp)¶ 返回对应于 POSIX 时间戳的 UTC
datetime
,其中tzinfo
值为None
。 (结果为简单型对象。)这可能引发
OverflowError
,如果时间戳数值超出所在平台 Cgmtime()
函数的支持范围的话,并会在gmtime()
报错时引发OSError
。 通常该数值会被限制在 1970 至 2038 年之间。要得到一个感知型
datetime
对象,应调用fromtimestamp()
:datetime.fromtimestamp(timestamp, timezone.utc)
在 POSIX 兼容的平台上,它等价于以下表达式:
datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(seconds=timestamp)
不同之处在于后一种形式总是支持完整年份范围:从
MINYEAR
到MAXYEAR
的开区间。警告
由于简单型
datetime
对象会被许多datetime
方法当作本地时间来处理,最好是使用感知型日期时间对象来表示 UTC 时间。 因此,创建表示特定 UTC 时间戳的日期时间对象的推荐方式是通过调用datetime.fromtimestamp(timestamp, tz=timezone.utc)
。在 3.3 版更改: 引发
OverflowError
而不是ValueError
,如果时间戳数值超出所在平台 Cgmtime()
函数的支持范围的话。 并会在gmtime()
出错时引发OSError
而不是ValueError
。
-
classmethod
datetime.
fromordinal
(ordinal)¶ 返回对应于预期格列高利历序号的
datetime
,其中公元 1 年 1 月 1 日的序号为 1。 除非1 <= ordinal <= datetime.max.toordinal()
否则会引发ValueError
。 结果的 hour, minute, second 和 microsecond 值均为 0,并且tzinfo
值为None
。
-
classmethod
datetime.
combine
(date, time, tzinfo=self.tzinfo)¶ 返回一个新的
datetime
对象,对象的日期部分等于给定的date
对象的值,而其时间部分等于给定的time
对象的值。 如果提供了 tzinfo 参数,其值会被用来设置结果的tzinfo
属性,否则将使用 time 参数的tzinfo
属性。对于任意
datetime
对象 d,d == datetime.combine(d.date(), d.time(), d.tzinfo)
。 如果 date 是一个datetime
对象,它的时间部分和tzinfo
属性会被忽略。在 3.6 版更改: 增加了 tzinfo 参数。
-
classmethod
datetime.
fromisoformat
(date_string)¶ 返回一个对应于
date.isoformat()
和datetime.isoformat()
所提供的某一种 date_string 的datetime
对象。特别地,此函数支持以下格式的字符串:
YYYY-MM-DD[*HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]]
其中
*
可以匹配任意的单个字符。警告
此函数 并不 支持解析任意 ISO 8601 字符串 —— 它的目的只是作为
datetime.isoformat()
的逆操作。 在第三方包 dateutil 中提供了一个更完善的 ISO 8601 解析器dateutil.parser.isoparse
。示例:
>>> 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 新版功能.
-
classmethod
datetime.
fromisocalendar
(year, week, day)¶ 返回以 year, week 和 day 值指明的 ISO 历法日期所对应的
datetime
。 该datetime 对象的非日期部分将使用其标准默认值来填充。 这是函数datetime.isocalendar()
的逆操作。3.8 新版功能.
-
classmethod
datetime.
strptime
(date_string, format)¶ 返回一个对应于 date_string,根据 format 进行解析得到的
datetime
对象。这相当于:
datetime(*(time.strptime(date_string, format)[0:6]))
如果 date_string 和 format 无法被
time.strptime()
解析或它返回一个不是时间元组的值,则将引发ValueError
。 要获取格式化指令的完整列表,请参阅 strftime() 和 strptime() 的行为。
类属性:
实例属性(只读):
-
datetime.
month
¶ 1 至 12(含)
-
datetime.
day
¶ 返回1到指定年月的天数间的数字。
-
datetime.
hour
¶ 取值范围是
range(24)
。
-
datetime.
minute
¶ 取值范围是
range(60)
。
-
datetime.
second
¶ 取值范围是
range(60)
。
-
datetime.
microsecond
¶ 取值范围是
range(1000000)
。
-
datetime.
fold
¶ 取值范围是
[0, 1]
。 用于在重复的时间段中消除边界时间歧义。 (当夏令时结束时回拨时钟或由于政治原因导致当明时区的 UTC 时差减少就会出现重复的时间段。) 取值 0 (1) 表示两个时刻早于(晚于)所代表的同一边界时间。3.6 新版功能.
支持的运算:
运算 |
结果 |
---|---|
|
(1) |
|
(2) |
|
(3) |
|
datetime2 是从 datetime1 去掉了一段 timedelta 的结果,如果
timedelta.days
> 0 则是在时间线上前进,如果timedelta.days
< 0 则是在时间线上后退。 该结果具有与输入的 datetime 相同的tzinfo
属性,并且操作完成后 datetime2 - datetime1 == timedelta。 如果 datetime2.year 将要小于MINYEAR
或大于MAXYEAR
则会引发OverflowError
。 请注意即使输入的是一个感知型对象,该方法也不会进行时区调整。计算 datetime2 使得 datetime2 + timedelta == datetime1。 与相加操作一样,结果具有与输入的 datetime 相同的
tzinfo
属性,即使输入的是一个感知型对象,该方法也不会进行时区调整。从一个
datetime
减去一个datetime
仅对两个操作数均为简单型或均为感知型时有定义。 如果一个是感知型而另一个是简单型,则会引发TypeError
。如果两个操作数都是简单型,或都是感知型并且具有相同的
tzinfo
属性,则tzinfo
属性会被忽略,并且结果会是一个使得datetime2 + t == datetime1
的timedelta
对象 t。 在此情况下不会进行时区调整。如果两个操作数都是感知型且具有不同的
tzinfo
属性,a-b
操作的效果就如同 a 和 b 首先被转换为简单型 UTC 日期时间。 结果将是(a.replace(tzinfo=None) - a.utcoffset()) - (b.replace(tzinfo=None) - b.utcoffset())
,除非具体实现绝对不溢出。当 datetime1 的时间在 datetime2 之前则认为 datetime1 小于 datetime2。
如果比较的一方是简单型而另一方是感知型,则如果尝试进行顺序比较将引发
TypeError
。 对于相等比较,简单型实例将永远不等于感知型实例。如果两个比较方都是感知型,且具有相同的
tzinfo
属性,则相同的tzinfo
属性会被忽略并对基本日期时间值进行比较。 如果两个比较方都是感知型且具有不同的tzinfo
属性,则两个比较方将首先通过减去它们的 UTC 差值(使用self.utcoffset()
获取)来进行调整。
实例方法:
-
datetime.
time
()¶ 返回具有同样 hour, minute, second, microsecond 和 fold 值的
time
对象。tzinfo
值为None
。 另请参见timetz()
方法。在 3.6 版更改: fold 值会被复制给返回的
time
对象。
-
datetime.
timetz
()¶ 返回具有同样 hour, minute, second, microsecond, fold 和 tzinfo 属性性的
time
对象。 另请参见time()
方法。在 3.6 版更改: fold 值会被复制给返回的
time
对象。
-
datetime.
replace
(year=self.year, month=self.month, day=self.day, hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)¶ 返回一个具有同样属性值的 datetime,除非通过任何关键字参数为某些属性指定了新值。 请注意可以通过指定
tzinfo=None
来从一个感知型 datetime 创建一个简单型 datetime 而不必转换日期和时间数据。3.6 新版功能: 增加了
fold
参数。
-
datetime.
astimezone
(tz=None)¶ 返回一个具有新的
tzinfo
属性 tz 的datetime
对象,并会调整日期和时间数据使得结果对应的 UTC 时间与 self 相同,但为 tz 时区的本地时间。如果给出了 tz,则它必须是一个
tzinfo
子类的实例,并且其utcoffset()
和dst()
方法不可返回None
。 如果 self 为简单型,它会被假定为基于系统时区表示的时间。如果调用时不传入参数 (或传入
tz=None
) 则将假定目标时区为系统的本地时区。 转换后 datetime 实例的.tzinfo
属性将被设为一个timezone
实例,时区名称和时差值将从 OS 获取。如果
self.tzinfo
为 tz,self.astimezone(tz)
等于 self: 不会对日期或时间数据进行调整。 否则结果为 tz 时区的本地时间,代表的 UTC 时间与 self 相同:在astz = dt.astimezone(tz)
之后,astz - astz.utcoffset()
将具有与dt - dt.utcoffset()
相同的日期和时间数据。如果你只是想要附加一个时区对象 tz 到一个 datetime 对象 dt 而不调整日期和时间数据,请使用
dt.replace(tzinfo=tz)
。 如果你只想从一个感知型 datetime 对象 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
()¶ 如果
tzinfo
为None
,则返回None
,否则返回self.tzinfo.utcoffset(self)
,并且在后者不返回None
或者一个幅度小于一天的timedelta
对象时将引发异常。在 3.7 版更改: UTC 时差不再限制为一个整数分钟值。
-
datetime.
dst
()¶ 如果
tzinfo
为None
,则返回None
,否则返回self.tzinfo.dst(self)
,并且在后者不返回None
或者一个幅度小于一天的timedelta
对象时将引发异常。在 3.7 版更改: DST 差值不再限制为一个整数分钟值。
-
datetime.
tzname
()¶ 如果
tzinfo
为None
,则返回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 会通过减去
d.utcoffset()
来标准化为 UTC 时间,并返回该标准化时间所对应的time.struct_time
。tm_isdst
会强制设为 0。 请注意如果 d.year 为MINYEAR
或MAXYEAR
并且 UTC 调整超出一年的边界则可能引发OverflowError
。警告
由于简单型
datetime
对象会被许多datetime
方法当作本地时间来处理,最好是使用感知型日期时间来表示 UTC 时间;因此,使用utcfromtimetuple
可能会给出误导性的结果。 如果你有一个表示 UTC 的简单型datetime
,请使用datetime.replace(tzinfo=timezone.utc)
将其改为感知型,这样你才能使用datetime.timetuple()
。
-
datetime.
toordinal
()¶ 返回日期的预期格列高利历序号。 与
self.date().toordinal()
相同。
-
datetime.
timestamp
()¶ 返回对应于
datetime
实例的 POSIX 时间戳。 此返回值是与time.time()
返回值类似的float
对象。简单型
datetime
实例会假定为代表本地时间,并且此方法依赖于平台的 Cmktime()
函数来执行转换。 由于在许多平台上datetime
支持的范围比mktime()
更广,对于极其遥远的过去或未来此方法可能引发OverflowError
。对于感知型
datetime
实例,返回值的计算方式为:(dt - datetime(1970, 1, 1, tzinfo=timezone.utc)).total_seconds()
3.3 新版功能.
在 3.6 版更改:
timestamp()
方法使用fold
属性来消除重复间隔中的时间歧义。注解
没有一个方法能直接从表示 UTC 时间的简单型
datetime
实例获取 POSIX 时间戳。 如果你的应用程序使用此惯例并且你的系统时区不是设为 UTC,你可以通过提供tzinfo=timezone.utc
来获取 POSIX 时间戳: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
不为 0YYYY-MM-DDTHH:MM:SS
,如果microsecond
为 0
如果
utcoffset()
返回值不为None
,则添加一个字符串来给出 UTC 时差:YYYY-MM-DDTHH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]
,如果microsecond
不为 0YYYY-MM-DDTHH:MM:SS+HH:MM[:SS[.ffffff]]
,如果microsecond
为 0
示例:
>>> 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'
)。它可以是以下值之一:'auto'
: 如果microsecond
为 0 则与'seconds'
相同,否则与'microseconds'
相同。'hours'
: 以两个数码的HH
格式 包含hour
。'milliseconds'
: 包含完整时间,但将秒值的小数部分截断至微秒。 格式为HH:MM:SS.sss
'microseconds'
: 以HH:MM:SS.ffffff
格式包含完整时间。
注解
排除掉的时间部分将被截断,而不是被舍入。
对于无效的 timespec 参数将引发
ValueError
:>>> 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.
ctime
()¶ 返回一个表示日期和时间的字符串:
>>> from datetime import datetime >>> 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()
则不会) 遵循 C 标准的平台上。
-
datetime.
strftime
(format)¶ 返回一个由显式格式字符串所指明的代表日期和时间的字符串,要获取格式指令的完整列表,请参阅 strftime() 和 strptime() 的行为。
-
datetime.
__format__
(format)¶ 与
datetime.strftime()
相同。 此方法使得为datetime
对象指定以 格式化字符串字面值 表示的格式化字符串以及使用str.format()
进行格式化成为可能。 要获取格式指令的完整列表,请参阅 strftime() 和 strptime() 的行为。
用法示例: 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
子类,它捕获 Kabul, Afghanistan 时区的信息,该时区使用 +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
对象¶
一个 time
对象代表某日的(本地)时间,它独立于任何特定日期,并可通过 tzinfo
对象来调整。
-
class
datetime.
time
(hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)¶ 所有参数都是可选的。 tzinfo 可以是
None
,或者是一个tzinfo
子类的实例。 其余的参数必须是在下面范围内的整数:0 <= hour < 24
,0 <= minute < 60
,0 <= second < 60
,0 <= microsecond < 1000000
,fold in [0, 1]
.
如果给出一个此范围以外的参数,则会引发
ValueError
。 所有参数值默认为0
,只有 tzinfo 默认为None
。
类属性:
实例属性(只读):
-
time.
hour
¶ 取值范围是
range(24)
。
-
time.
minute
¶ 取值范围是
range(60)
。
-
time.
second
¶ 取值范围是
range(60)
。
-
time.
microsecond
¶ 取值范围是
range(1000000)
。
-
time.
fold
¶ 取值范围是
[0, 1]
。 用于在重复的时间段中消除边界时间歧义。 (当夏令时结束时回拨时钟或由于政治原因导致当明时区的 UTC 时差减少就会出现重复的时间段。) 取值 0 (1) 表示两个时刻早于(晚于)所代表的同一边界时间。3.6 新版功能.
time
对象支持 time
与 time
的比较,当 a 时间在 b 之前时,则认为 a 小于 b。 如果比较的一方是简单型而另一方是感知型,则如果尝试进行顺序比较将引发 TypeError
。 对于相等比较,简单型实例将永远不等于感知型实例。
如果两个比较方都是感知型,且具有相同的 tzinfo
属性,相同的 tzinfo
属性会被忽略并对基本时间值进行比较。 如果两个比较方都是感知型且具有不同的 tzinfo
属性,两个比较方将首先通过减去它们的 UTC 时差(从 self.utcoffset()
获取)来进行调整。 为了防止将混合类型比较回退为基于对象地址的默认比较,当 time
对象与不同类型的对象比较时,将会引发 TypeError
,除非比较运算符是 ==
或 !=
。 在后两种情况下将分别返回 False
或 True
。
在布尔运算时,time
对象总是被视为真值。
在 3.5 版更改: 在 Python 3.5 之前,如果一个 time
对象代表 UTC 午夜零时则会被视为假值。 此行为被认为容易引发困惑和错误,因此从 Python 3.5 起已被去除。 详情参见 bpo-13936。
其他构造方法:
-
classmethod
time.
fromisoformat
(time_string)¶ 返回对应于
time.isoformat()
所提供的某种 time_string 格式的time
。 特别地,此函数支持以下格式的字符串:HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]
警告
此方法 并不 支持解析任意 ISO 8601 字符串。 它的目的只是作为
time.isoformat()
的逆操作。示例:
>>> 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 新版功能.
实例方法:
-
time.
replace
(hour=self.hour, minute=self.minute, second=self.second, microsecond=self.microsecond, tzinfo=self.tzinfo, * fold=0)¶ 返回一个具有同样属性值的
time
,除非通过任何关键字参数指定了某些属性值。 请注意可以通过指定tzinfo=None
从一个感知型time
创建一个简单型time
,而不必转换时间数据。3.6 新版功能: 增加了
fold
参数。
-
time.
isoformat
(timespec='auto')¶ 返回表示为下列 ISO 8601 格式之一的时间字符串:
HH:MM:SS.ffffff
,如果microsecond
不为 0HH:MM:SS
,如果microsecond
为 0HH:MM:SS.ffffff+HH:MM[:SS[.ffffff]]
,如果utcoffset()
不返回None
HH:MM:SS+HH:MM[:SS[.ffffff]]
,如果microsecond
为 0 并且utcoffset()
不返回None
可选参数 timespec 要包含的额外时间组件值 (默认为
'auto'
)。它可以是以下值之一:'auto'
: 如果microsecond
为 0 则与'seconds'
相同,否则与'microseconds'
相同。'hours'
: 以两个数码的HH
格式 包含hour
。'milliseconds'
: 包含完整时间,但将秒值的小数部分截断至微秒。 格式为HH:MM:SS.sss
'microseconds'
: 以HH:MM:SS.ffffff
格式包含完整时间。
注解
排除掉的时间部分将被截断,而不是被舍入。
对于无效的 timespec 参数将引发
ValueError
。示例:
>>> 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 新版功能: 增加了 timespec 参数。
-
time.
__str__
()¶ 对于时间对象 t,
str(t)
等价于t.isoformat()
。
-
time.
strftime
(format)¶ 返回一个由显式格式字符串所指明的代表时间的字符串。 要获取格式指令的完整列表,请参阅 strftime() 和 strptime() 的行为。
-
time.
__format__
(format)¶ 与
time.strftime()
相同。 此方法使得为time
对象指定以 格式化字符串字面值 表示的格式化字符串以及使用str.format()
进行格式化成为可能。 要获取格式指令的完整列表,请参阅 strftime() 和 strptime() 的行为。
-
time.
utcoffset
()¶ 如果
tzinfo
为None
,则返回None
,否则返回self.tzinfo.utcoffset(None)
,并且在后者不返回None
或一个幅度小于一天的 atimedelta
对象时将引发异常。在 3.7 版更改: UTC 时差不再限制为一个整数分钟值。
-
time.
dst
()¶ 如果
tzinfo
为None
,则返回None
,否则返回self.tzinfo.dst(None)
,并且在后者不返回None
或者一个幅度小于一天的timedelta
对象时将引发异常。在 3.7 版更改: DST 差值不再限制为一个整数分钟值。
-
time.
tzname
()¶ 如果
tzinfo
为None
,则返回None
,否则返回self.tzinfo.tzname(None)
,如果后者不返回None
或者一个字符串对象则将引发异常。
用法示例: time
¶
使用 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
对象¶
-
class
datetime.
tzinfo
¶ 这是一个抽象基类,也就是说该类不应被直接实例化。 请定义
tzinfo
的子类来捕获有关特定时区的信息。tzinfo
的(某个实体子类)的实例可以被传给datetime
和time
对象的构造器。 这些对象会将它们的属性视为对应于本地时间,并且tzinfo
对象支持展示本地时间与 UTC 的差值、时区名称以及 DST 差值的方法,都是与传给它们的日期或时间对象的相对值。你需要派生一个实体子类,并且(至少)提供你使用
datetime
方法所需要的标准tzinfo
方法的实现。datetime
模块提供了timezone
,这是tzinfo
的一个简单实体子类,它能以与 UTC 的固定差值来表示不同的时区,例如 UTC 本身或北美的 EST 和 EDT。对于封存操作的特殊要求:一个
tzinfo
子类必须具有可不带参数调用的__init__()
方法,否则它虽然可以被封存,但可能无法再次解封。 这是个技术性要求,在未来可能会被取消。一个
tzinfo
的实体子类可能需要实现以下方法。 具体需要实现的方法取决于感知型datetime
对象如何使用它。 如果有疑问,可以简单地全都实现。
-
tzinfo.
utcoffset
(dt)¶ 将本地时间与 UTC 时差返回为一个
timedelta
对象,如果本地时区在 UTC 以东则为正值。 如果本地时区在 UTC 以西则为负值。这表示与 UTC 的 总计 时差;举例来说,如果一个
tzinfo
对象同时代表时区和 DST 调整,则utcoffset()
应当返回两者的和。 如果 UTC 时差不确定则返回None
。 在其他情况下返回值必须为一个timedelta
对象,其取值严格限制于-timedelta(hours=24)
和timedelta(hours=24)
之间(差值的幅度必须小于一天)。 大多数utcoffset()
的实现看起来可能像是以下两者之一:return CONSTANT # fixed-offset class return CONSTANT + self.dst(dt) # daylight-aware class
如果
utcoffset()
返回值不为None
,则dst()
也不应返回None
。默认的
utcoffset()
实现会引发NotImplementedError
。在 3.7 版更改: UTC 时差不再限制为一个整数分钟值。
-
tzinfo.
dst
(dt)¶ 将夏令时(DST)调整返回为一个
timedelta
对象,如果 DST 信息未知则返回None
。如果 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)
必须为具有同样的
tzinfo
子类实例且dt.tzinfo == tz
的每个datetime
对象 dt 返回同样的结果,此表达式会产生时区的“标准时差”,它不应取决于具体日期或时间,只取决于地理位置。datetime.astimezone()
的实现依赖此方法,但无法检测违反规则的情况;确保符合规则是程序员的责任。 如果一个tzinfo
子类不能保证这一点,也许可以重载tzinfo.fromutc()
的默认实现以便在任何情况下与astimezone()
正确配合。大多数
dst()
的实现可能会如以下两者之一:def dst(self, dt): # a fixed-offset class: doesn't account for DST return timedelta(0)
或者:
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 差值不再限制为一个整数分钟值。
-
tzinfo.
tzname
(dt)¶ 将对应于
datetime
对象 dt 的时区名称作为字符串返回。datetime
模块没有定义任何字符串名称相关内容,也不要求名称有任何特定含义。 例如 "GMT", "UTC", "-500", "-5:00", "EDT", "US/Eastern", "America/New York" 都是有效的返回值。 如果字符串名称未知则返回None
。 请注意这是一个方法而不是一个固定的字符串,这主要是因为某些tzinfo
子类可能需要根据所传入的特定 dt 值返回不同的名称,特别是当tzinfo
类要负责处理夏令时的时候。默认的
tzname()
实现会引发NotImplementedError
。
这些方法会被 datetime
或 time
对象调用,用来与它们的同名方法相对应。 datetime
对象会将自身作为传入参数,而 time
对象会将 None
作为传入参数。 这样 tzinfo
子类的方法应当准备好接受 dt 参数值为 None
或是 datetime
类的实例。
当传入 None
时,应当由类的设计者来决定最佳回应方式。 例如,返回 None
适用于希望该类提示时间对象不参与 tzinfo
协议处理。 让 utcoffset(None)
返回标准 UTC 时差也许会更有用处,因为并没有其他可用于发现标准时差的约定惯例。
当传入一个 datetime
对象来回应 datetime
方法时,dt.tzinfo
与 self 是同一对象。 tzinfo
方法可以依赖这一点,除非用户代码直接调用了 tzinfo
方法。 此行为的目的是使得 tzinfo
方法将 dt 解读为本地时间,而不需要担心其他时区的相关对象。
还有一个额外的 tzinfo
方法,某个子类可能会希望重载它:
-
tzinfo.
fromutc
(dt)¶ 此方法会由默认的
datetime.astimezone()
实现来调用。 当被其调用时,dt.tzinfo
为 self,并且 dt 的日期和时间数据会被视为表示 UTC 时间,fromutc()
的目标是调整日期和时间数据,返回一个等价的 datetime 来表示 self 的本地时间。大多数
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 从三月的第二个星期天 1:59 (EST) 之后一分钟开始,并在十一月的第一天星期天 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 开始时(即 "start" 行),本地时钟从 1:59 跳到 3:00。 形式为 2:MM 的时间值在那一天是没有意义的,因此在 DST 开始那一天 astimezone(Eastern)
不会输出包含 hour == 2
的结果。 例如,在 2016 年春季时钟向前调整时,我们得到:
>>> 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 结束时(见 "end" 行),会有更糟糕的潜在问题:本地时间值中有一个小时是不可能没有歧义的:夏令时的最后一小时。 即以北美东部时间表示当天夏令时结束时的形式为 5:MM UTC 的时间。 本地时钟从 1:59 (夏令时) 再次跳回到 1:00 (标准时)。 形式为 1:MM 的本地时间就是有歧义的。 此时 astimezone()
是通过将两个相邻的 UTC 小时映射到两个相同的本地小时来模仿本地时钟的行为。 在这个北美东部时间的示例中,形式为 5:MM 和 6:MM 的 UTC 时间在转换为北美东部时间时都将被映射到 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
请注意不同的 datetime
实例仅通过 fold
属性值来加以区分,它们在比较时会被视为相等。
不允许时间显示存在歧义的应用需要显式地检查 fold
属性的值,或者避免使用混合式的 tzinfo
子类;当使用 timezone
或者任何其他固定差值的 tzinfo
子类例如仅表示 EST(固定差值 -5 小时)或仅表示 EDT(固定差值 -4 小时)的类时是不会有歧义的。
参见
- dateutil.tz
datetime
模块有一个基本timezone
类(用来处理任意与 UTC 的固定时差)及其timezone.utc
属性(一个 UTC 时区实例)。dateutil.tz 库将 IANA 时区数据库 (又名 Olson 数据库) 引入 Python 并推荐使用。
- IANA 时区数据库
该时区数据库 (通常称为 tz, tzdata 或 zoneinfo) 包含大量代码和数据用来表示全球许多有代表性的地点的本地时间的历史信息。 它会定期进行更新以反映各政治实体对时区边界、UTC 差值和夏令时规则的更改。
timezone
对象¶
timezone
类是 tzinfo
的子类,它的每个实例都代表一个以与 UTC 的固定时差来定义的时区。
此类的对象不可被用于代表某些特殊地点的时区信息,这些地点在一年的不同日期会使用不同的时差,或是在历史上对民用时间进行过调整。
-
class
datetime.
timezone
(offset, name=None)¶ offset 参数必须指定为一个
timedelta
对象,表示本地时间与 UTC 的时差。 它必须严格限制于-timedelta(hours=24)
和timedelta(hours=24)
之间,否则会引发ValueError
。name 参数是可选的。 如果指定则必须为一个字符串,它将被用作
datetime.tzname()
方法的返回值。3.2 新版功能.
在 3.7 版更改: UTC 时差不再限制为一个整数分钟值。
-
timezone.
utcoffset
(dt)¶ 返回当
timezone
实例被构造时指定的固定值。dt 参数会被忽略。 返回值是一个
timedelta
实例,其值等于本地时间与 UTC 之间的时差。在 3.7 版更改: UTC 时差不再限制为一个整数分钟值。
-
timezone.
tzname
(dt)¶ 返回当
timezone
实例被构造时指定的固定值。如果没有在构造器中提供 name,则
tzname(dt)
所返回的名称将根据offset
值按以下规则生成。 如果 offset 为timedelta(0)
,则名称为“UTC”,否则为字符串UTC±HH:MM
,其中 ± 为offset
的正负符号,HH 和 MM 分别为表示offset.hours
和offset.minutes
的两个数码。在 3.6 版更改: 由
offset=timedelta(0)
生成的名称现在为简单的 'UTC' 而不再是'UTC+00:00'
。
-
timezone.
dst
(dt)¶ 总是返回
None
。
类属性:
-
timezone.
utc
¶ UTC 时区,
timezone(timedelta(0))
。
strftime()
和 strptime()
的行为¶
date
, datetime
和 time
对象都支持 strftime(format)
方法,可用来创建由一个显式格式字符串所控制的表示时间的字符串。
相反地,datetime.strptime()
类会根据表示日期和时间的字符串和相应的格式字符串来创建一个 datetime
对象。
下表提供了 strftime()
与 strptime()
的高层级比较:
|
|
|
---|---|---|
用法 |
根据给定的格式将对象转换为字符串 |
将字符串解析为给定相应格式的 |
方法类型 |
实例方法 |
类方法 |
方法 |
||
签名 |
|
|
strftime()
和 strptime()
Format Codes¶
以下列表显示了 1989 版 C 标准所要求的全部格式代码,它们在带有标准 C 实现的所有平台上均可用。
指令 |
意义 |
示例 |
注释 |
---|---|---|---|
|
当地工作日的缩写。 |
Sun, Mon, ..., Sat
(en_US);
So, Mo, ..., Sa
(de_DE)
|
(1) |
|
本地化的星期中每日的完整名称。 |
Sunday, Monday, ...,
Saturday (en_US);
Sonntag, Montag, ...,
Samstag (de_DE)
|
(1) |
|
以十进制数显示的工作日,其中0表示星期日,6表示星期六。 |
0, 1, ..., 6 |
|
|
补零后,以十进制数显示的月份中的一天。 |
01, 02, ..., 31 |
(9) |
|
当地月份的缩写。 |
Jan, Feb, ..., Dec
(en_US);
Jan, Feb, ..., Dez
(de_DE)
|
(1) |
|
本地化的月份全名。 |
January, February,
..., December (en_US);
Januar, Februar, ...,
Dezember (de_DE)
|
(1) |
|
补零后,以十进制数显示的月份。 |
01, 02, ..., 12 |
(9) |
|
补零后,以十进制数表示的,不带世纪的年份。 |
00, 01, ..., 99 |
(9) |
|
十进制数表示的带世纪的年份。 |
0001, 0002, ..., 2013, 2014, ..., 9998, 9999 |
(2) |
|
以补零后的十进制数表示的小时(24 小时制)。 |
00, 01, ..., 23 |
(9) |
|
以补零后的十进制数表示的小时(12 小时制)。 |
01, 02, ..., 12 |
(9) |
|
本地化的 AM 或 PM 。 |
AM, PM (en_US);
am, pm (de_DE)
|
(1), (3) |
|
补零后,以十进制数显示的分钟。 |
00, 01, ..., 59 |
(9) |
|
补零后,以十进制数显示的秒。 |
00, 01, ..., 59 |
(4), (9) |
|
以十进制数表示的毫秒,在左侧补零。 |
000000, 000001, ..., 999999 |
(5) |
|
UTC 偏移量,格式为 |
(空), +0000, -0400, +1030, +063415, -030712.345216 |
(6) |
|
时区名称(如果对象为简单型则为空字符串)。 |
(空), UTC, EST, CST |
|
|
以补零后的十进制数表示的一年中的日序号。 |
001, 002, ..., 366 |
(9) |
|
以补零后的十进制数表示的一年中的周序号(星期日作为每周的第一天)。 在新的一年中第一个星期日之前的所有日子都被视为是在第 0 周。 |
00, 01, ..., 53 |
(7), (9) |
|
以十进制数表示的一年中的周序号(星期一作为每周的第一天)。 在新的一年中第一个第期一之前的所有日子都被视为是在第 0 周。 |
00, 01, ..., 53 |
(7), (9) |
|
本地化的适当日期和时间表示。 |
Tue Aug 16 21:30:00
1988 (en_US);
Di 16 Aug 21:30:00
1988 (de_DE)
|
(1) |
|
本地化的适当日期表示。 |
08/16/88 (None);
08/16/1988 (en_US);
16.08.1988 (de_DE)
|
(1) |
|
本地化的适当时间表示。 |
21:30:00 (en_US);
21:30:00 (de_DE)
|
(1) |
|
字面的 |
% |
为了方便起见,还包括了C89标准不需要的其他一些指令。这些参数都对应于ISO 8601日期值。
指令 |
意义 |
示例 |
注释 |
---|---|---|---|
|
带有世纪的 ISO 8601 年份,表示包含大部分 ISO 星期 ( |
0001, 0002, ..., 2013, 2014, ..., 9998, 9999 |
(8) |
|
以十进制数显示的 ISO 8601 星期中的日序号,其中 1 表示星期一。 |
1, 2, ..., 7 |
|
|
以十进制数显示的 ISO 8601 星期,以星期一作为每周的第一天。 第 01 周为包含 1 月 4 日的星期。 |
01, 02, ..., 53 |
(8), (9) |
这些代码可能不是在所有平台上都可与 strftime()
方法配合使用。 ISO 8601 年份和 ISO 8601 星期指令并不能与上面的年份和星期序号指令相互替代。 调用 strptime()
时传入不完整或有歧义的 ISO 8601 指令将引发 ValueError
。
对完整格式代码集的支持在不同平台上有所差异,因为 Python 要调用所在平台的 C 库的 strftime()
函数,而不同平台的差异是很常见的。 要查看你所用平台所支持的完整格式代码集,请参阅 strftime(3) 文档。
3.6 新版功能: 增加了 %G
, %u
和 %V
。
技术细节¶
总体而言,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
或只返回一个空字符串。
注释:
由于此格式依赖于当前区域设置,因此对具体输出值应当保持谨慎预期。 字段顺序会发生改变(例如 "month/day/year" 与 "day/month/year"),并且输出可能包含使用区域设置所指定的默认编码格式的 Unicode 字符(例如如果当前区域为
ja_JP
,则默认编码格式可能为eucJP
,SJIS
或utf-8
中的一个;使用locale.getlocale()
可确定当前区域设置的编码格式)。strptime()
方法能够解析整个 [1, 9999] 范围内的年份,但 < 1000 的年份必须加零填充为 4 位数字宽度。在 3.2 版更改: 在之前的版本中,
strftime()
方法只限于 >= 1900 的年份。在 3.3 版更改: 在版本3.2中,
strftime()
方法只限于 years >= 1000。当与
strptime()
方法一起使用时,如果使用%I
指令来解析小时,%p
指令只影响输出小时字段。当与
strptime()
方法一起使用时,%f
指令可接受一至六个数码及左边的零填充。%f
是对 C 标准中格式字符集的扩展(但单独在 datetime 对象中实现,因此它总是可用)。对于简单型对象,
%z
and%Z
格式代码会被替换为空字符串。对于一个感知型对象而言:
%z
utcoffset()
会被转换为±HHMM[SS[.ffffff]]
形式的字符串,其中HH
为给出 UTC 时差的小时部分的 2 位数码字符串,MM
为给出 UTC 时差的分钟部分的 2 位数码字符串,SS
为给出 UTC 时差的秒部分的 2 位数码字符串,而ffffff
为给出 UTC 时差的微秒部分的 6 位数码字符串。 当时差为整数秒时ffffff
部分将被省略,而当时差为整数分钟时ffffff
和SS
部分都将被省略。 例如,如果utcoffset()
返回timedelta(hours=-3, minutes=-30)
,则%z
会被替换为字符串'-0330'
。
在 3.7 版更改: UTC 时差不再限制为一个整数分钟值。
在 3.7 版更改: 当提供
%z
指令给strptime()
方法时,UTC 差值可以在时、分和秒之间使用冒号分隔符。 例如,'+01:00:00'
将被解读为一小时的差值。 此外,提供'Z'
就相当于'+00:00'
。%Z
如果
tzname()
返回None
,%Z
会被替换为一个空字符串。 在其他情况下%Z
会被替换为返回值,这必须为一个字符串。
当与
strptime()
方法一起使用时,%U
和%W
仅用于指定星期几和日历年份 (%Y
) 的计算。类似于
%U
和%W
,%V
仅用于在strptime()
格式字符串中指定星期几和 ISO 年份 (%G
) 的计算。 还要注意%G
和%Y
是不可交换的。当于
strptime()
方法一起使用时,前导的零在格式%d
,%m
,%H
,%I
,%M
,%S
,%J
,%U
,%W
和%V
中是可选的。 格式%y
不要求有前导的零。
脚注
- 1
就是说如果我们忽略相对论效应的话。
- 2
这与 Dershowitz 和 Reingold 所著 Calendrical Calculations 中“预期格列高利”历法的定义一致,它是适用于该书中所有运算的基础历法。 请参阅该书了解在预期格利高利历序列与许多其他历法系统之间进行转换的算法。
- 3
请参阅 R. H. van Gent 所著 ` ISO 8601 历法的数学指导 <https://www.staff.science.uu.nl/~gent0113/calendar/isocalendar.htm>`_ 以获取更完整的说明。
- 4
传入
datetime.strptime('Feb 29', '%b %d')
将导致错误,因为1900
不是闰年。