1. datetime:日期和时间值管理
datetime包含一些函数和类,用于完成日期和时间的解析、格式化和算术运算。
1.1 时间
时间值用time类表示。time实例包含hour、minute、second和microsecond属性,还可以包含时区信息。
importdatetime
t= datetime.time(1, 2, 3)print(t)print('hour :', t.hour)print('minute :', t.minute)print('second :', t.second)print('microsecond:', t.microsecond)print('tzinfo :', t.tzinfo)
初始化time实例的参数是可选的,但默认值0不太可能是正确的。
time实例只包含时间值,而不包含与时间相关的日期值。
importdatetimeprint('Earliest :', datetime.time.min)print('Latest :', datetime.time.max)print('Resolution:', datetime.time.resolution)
min和max类属性可以反映一天中的合法时间范围。
time的分辨率被限制为整微秒值。
importdatetimefor m in [1, 0, 0.1, 0.6]:try:print('{:02.1f} :'.format(m),
datetime.time(0, 0, 0, microsecond=m))exceptTypeError as err:print('ERROR:', err)
如果微秒为浮点值,则其会产生一个TypeError。
1.2 日期
日历日期值用date类表示。date实例包含year、month和day属性。使用today()类方法很容易创建一个当前日期的日期实例。
importdatetime
today=datetime.date.today()print(today)print('ctime :', today.ctime())
tt=today.timetuple()print('tuple : tm_year =', tt.tm_year)print('tm_mon =', tt.tm_mon)print('tm_mday =', tt.tm_mday)print('tm_hour =', tt.tm_hour)print('tm_min =', tt.tm_min)print('tm_sec =', tt.tm_sec)print('tm_wday =', tt.tm_wday)print('tm_yday =', tt.tm_yday)print('tm_isdst =', tt.tm_isdst)print('ordinal:', today.toordinal())print('Year :', today.year)print('Mon :', today.month)print('Day :', today.day)
下面这个例子采用多种不同格式来打印当前日期。
还有一些类方法可以由POSIX时间戳或Gregorian日历中表示日期值的整数(第1年的1月1日对应的值为1,以后每天对应的值逐个加1)来创建date实例。
importdatetimeimporttime
o= 733114
print('o :', o)print('fromordinal(o) :', datetime.date.fromordinal(o))
t=time.time()print('t :', t)print('fromtimestamp(t):', datetime.date.fromtimestamp(t))
这个例子表明fromordinal()和fromtimestamp()使用了不同的值类型。
与time类类似,可以使用min和max属性确定所支持的日期值范围。
importdatetimeprint('Earliest :', datetime.date.min)print('Latest :', datetime.date.max)print('Resolution:', datetime.date.resolution)
日期的分辨率为整天。
创建新的date实例还有一种方法,可以使用现有日期的replace()方法来创建。
importdatetime
d1= datetime.date(2008, 3, 29)print('d1:', d1.ctime())
d2= d1.replace(year=2009)print('d2:', d2.ctime())
1.3 timedelta
通过对两个datetime对象完成算术运算,或者结合使用datetime和timedelta,可以计算出将来和过去的日期。将两个日期相减可以生成一个timedelta,还可以对某个日期增加或减去一个timedelta来生成另一个日期。timedelta的内部值按日、秒和微秒存储。
importdatetimeprint('microseconds:', datetime.timedelta(microseconds=1))print('milliseconds:', datetime.timedelta(milliseconds=1))print('seconds :', datetime.timedelta(seconds=1))print('minutes :', datetime.timedelta(minutes=1))print('hours :', datetime.timedelta(hours=1))print('days :', datetime.timedelta(days=1))print('weeks :', datetime.timedelta(weeks=1))
传入构造函数的中间值会被转换为日、秒和微秒。
一个timedelta的完整时间段可以使用total_seconds()得到,并作为一个秒表返回。
importdatetimefor delta in [datetime.timedelta(microseconds=1),
datetime.timedelta(milliseconds=1),
datetime.timedelta(seconds=1),
datetime.timedelta(minutes=1),
datetime.timedelta(hours=1),
datetime.timedelta(days=1),
datetime.timedelta(weeks=1),
]:print('{:15} = {:8} seconds'.format(
str(delta), delta.total_seconds())
)
返回值是一个浮点数,因为有些时间段不到1秒。
1.4 日期算术运算
日期算术运算使用标准算术操作符来完成。
importdatetime
today=datetime.date.today()print('Today :', today)
one_day= datetime.timedelta(days=1)print('One day :', one_day)
yesterday= today -one_dayprint('Yesterday:', yesterday)
tomorrow= today +one_dayprint('Tomorrow :', tomorrow)print()print('tomorrow - yesterday:', tomorrow -yesterday)print('yesterday - tomorrow:', yesterday - tomorrow)
这个处理日期对象的例子展示了如何使用timedelta对象计算新日期,另外,这里将日期实例相减来生成timedelta(包括一个负差异值)。
timedelta对象还支持与整数、浮点数和其他timedelta实例的算术运算。
importdatetime
one_day= datetime.timedelta(days=1)print('1 day :', one_day)print('5 days :', one_day * 5)print('1.5 days :', one_day * 1.5)print('1/4 day :', one_day / 4)#assume an hour for lunch
work_day = datetime.timedelta(hours=7)
meeting_length= datetime.timedelta(hours=1)print('meetings per day :', work_day / meeting_length)
在这个例子中,计算了一天的多个倍数,得到的timedelta包含相应的天数或小时数。
最后这个例子展示了如何结合两个timedelta对象来计算值。在这里,结果是一个浮点数。
1.5 比较值
日期和时间值都可以使用标准比较操作符来比较,从而确定哪一个在前,哪一个在后。
importdatetimeimporttimeprint('Times:')
t1= datetime.time(12, 55, 0)print('t1:', t1)
t2= datetime.time(13, 5, 0)print('t2:', t2)print('t1 < t2:', t1
d1=datetime.date.today()print('d1:', d1)
d2= datetime.date.today() + datetime.timedelta(days=1)print('d2:', d2)print('d1 > d2:', d1 > d2)
支持所有比较操作符。
1.6 结合日期和时间
使用datetime类可以存储由日期和时间分量构成的值。类似于date,可以使用很多便利的类方法来从其他常用值创建datetime实例。
importdatetimeprint('Now :', datetime.datetime.now())print('Today :', datetime.datetime.today())print('UTC Now:', datetime.datetime.utcnow())print()
FIELDS=['year', 'month', 'day','hour', 'minute', 'second','microsecond',
]
d=datetime.datetime.now()for attr inFIELDS:print('{:15}: {}'.format(attr, getattr(d, attr)))
可以想见,datetime实例包含date和time对象的所有属性。
与date类似,datetime提供了便利的类方法来创建新实例。它还包括fromordinal()和fromtimestamp()。
importdatetime
t= datetime.time(1, 2, 3)print('t :', t)
d=datetime.date.today()print('d :', d)
dt=datetime.datetime.combine(d, t)print('dt:', dt)
利用combine(),可以由一个date实例和一个time实例创建一个datetime实例。
1.7 格式化和解析
datetime对象的默认字符串表示使用ISO-8601格式(YYYY-MM-DDTHH:MM:SS.mmmmmm)。可以使用strftime()生成其他格式。
importdatetime
format= "%a %b %d %H:%M:%S %Y"today=datetime.datetime.today()print('ISO :', today)
s=today.strftime(format)print('strftime:', s)
d=datetime.datetime.strptime(s, format)print('strptime:', d.strftime(format))
使用datetime.strptime()可以将格式化的字符串转换为datetime实例。
还可以对Python的字符串格式化微语言使用同样的格式化代码,只需要把这些格式化放在格式化字符串字段规范的 : 后面。
importdatetime
today=datetime.datetime.today()print('ISO :', today)print('format(): {:%a %b %d %H:%M:%S %Y}'.format(today))
每个datetime格式化代码都必须有%前缀,后面的冒号会作为字面量字符包含在输出中。
strptime/strftime格式化代码:
符号含义例
%a
星期几的缩写
'Wed'
%A
工作日全名
'Wednesday'
%w
工作日编号– 0(星期日)至6(星期六)
'3'
%d
每月的某天(零填充)
'13'
%b
缩写的月份名称
'Jan'
%B
月份全称
'January'
%m
一年中的月份
'01'
%y
没有世纪的年份
'16'
%Y
百年纪念
'2016'
%H
从24小时制开始的小时数
'17'
%I
从12小时制开始的小时数
'05'
%p
上午下午
'PM'
%M
分钟
'00'
%S
秒
'00'
%f
微秒
'000000'
%z
时区感知对象的UTC偏移量
'-0500'
%Z
时区名称
'EST'
%j
一年中的一天
'013'
%W
一年中的第几周
'02'
%c
当前语言环境的日期和时间表示
'Wed Jan 13 17:00:00 2016'
%x
当前语言环境的日期表示
'01/13/16'
%X
当前语言环境的时间表示
'17:00:00'
%%
文字%字符
'%'
1.8 时区
在datetime中,时区由tzinfo的子类表示。由于tzinfo是一个抽象基类,实际使用时,应用需要定义它的一个子类,并为一些方法提供适当的实现。
datetime在类timezone中确实包含一个原生实现,该类使用了一个固定的UTC偏移。这个实现不支持一年中不同日期有不同的偏移值,如有些地方采用夏令时,或者有些地方UTC偏移会随时间改变。
importdatetime
min6= datetime.timezone(datetime.timedelta(hours=-6))
plus6= datetime.timezone(datetime.timedelta(hours=6))
d=datetime.datetime.now(min6)print(min6, ':', d)print(datetime.timezone.utc, ':',
d.astimezone(datetime.timezone.utc))print(plus6, ':', d.astimezone(plus6))#convert to the current system timezone
d_system =d.astimezone()print(d_system.tzinfo, ':', d_system)
要把一个datetime值从一个时区转换为另一个时区,可以使用astimezone()。在前面的例子中,显示了UTC两侧正负6小时的两个不同时区,另外还使用了由datetime.timezone得到的utc实例来作为参考。最后的输出行显示了系统时区的值,这是不提供任何参数调用astimezone()得到的。