1. datetime:日期和时间值管理
datetime包含一些函数和类,用于完成日期和时间的解析、格式化和算术运算。
1.1 时间
时间值用time类表示。time实例包含hour、minute、second和microsecond属性,还可以包含时区信息。
import datetime 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实例只包含时间值,而不包含与时间相关的日期值。
import datetime print('Earliest :', datetime.time.min) print('Latest :', datetime.time.max) print('Resolution:', datetime.time.resolution)
min和max类属性可以反映一天中的合法时间范围。
time的分辨率被限制为整微秒值。
import datetime for m in [1, 0, 0.1, 0.6]: try: print('{:02.1f} :'.format(m), datetime.time(0, 0, 0, microsecond=m)) except TypeError as err: print('ERROR:', err)
如果微秒为浮点值,则其会产生一个TypeError。
1.2 日期
日历日期值用date类表示。date实例包含year、month和day属性。使用today()类方法很容易创建一个当前日期的日期实例。
import datetime 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实例。
import datetime import time 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属性确定所支持的日期值范围。
import datetime print('Earliest :', datetime.date.min) print('Latest :', datetime.date.max) print('Resolution:', datetime.date.resolution)
日期的分辨率为整天。
创建新的date实例还有一种方法,可以使用现有日期的replace()方法来创建。
import datetime 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的内部值按日、秒和微秒存储。
import datetime print('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()得到,并作为一个秒表返回。
import datetime for 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 日期算术运算
日期算术运算使用标准算术操作符来完成。
import datetime today = datetime.date.today() print('Today :', today) one_day = datetime.timedelta(days=1) print('One day :', one_day) yesterday = today - one_day print('Yesterday:', yesterday) tomorrow = today + one_day print('Tomorrow :', tomorrow) print() print('tomorrow - yesterday:', tomorrow - yesterday) print('yesterday - tomorrow:', yesterday - tomorrow)
这个处理日期对象的例子展示了如何使用timedelta对象计算新日期,另外,这里将日期实例相减来生成timedelta(包括一个负差异值)。
timedelta对象还支持与整数、浮点数和其他timedelta实例的算术运算。
import datetime 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 比较值
日期和时间值都可以使用标准比较操作符来比较,从而确定哪一个在前,哪一个在后。
import datetime import time print('Times:') t1 = datetime.time(12, 55, 0) print(' t1:', t1) t2 = datetime.time(13, 5, 0) print(' t2:', t2) print(' t1 < t2:', t1 < t2) print() print('Dates:') 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实例。
import datetime print('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 in FIELDS: print('{:15}: {}'.format(attr, getattr(d, attr)))
可以想见,datetime实例包含date和time对象的所有属性。
与date类似,datetime提供了便利的类方法来创建新实例。它还包括fromordinal()和fromtimestamp()。
import datetime 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()生成其他格式。
import datetime 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的字符串格式化微语言使用同样的格式化代码,只需要把这些格式化放在格式化字符串字段规范的 : 后面。
import datetime 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偏移会随时间改变。
import datetime 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()得到的。