我们可以看到datetime 模块下面还有好几个具体的类,下面分别从这几个类来分析datetime 模块:
1991
9999-12-31
下面我们仍然使用apihelper (使用见《python 学习笔记 9 -- Python强大的自省简析》)来查看date 类还提供了哪些强大的方法:
以当前时间获取一个日期对象
>>> today = datetime.date.today()
>>> today
datetime.date(2014, 7, 8)
将一个日期对象转化为ctime() 形式的字符串
>>> date.date.ctime(today)
'Tue Jul 8 00:00:00 2014'
对于日期对象,支持使用replace 方法直接修改具体项:
>>> da = datetime.date(2008, 10, 1)
>>> print da
2008-10-01
>>> print da.replace(2001, 1, 1) # 不指定,可全部进行修改
2001-01-01
>>> print da.replace(year=2009, day=13) # 符合python 的参数习惯,可以指定修改某一参数
2009-10-13
以ISO 8601 格式("YYYY-MM-DD")返回一个日期对象:
>>> datetime.date.isoformat(today)
'2014-07-08'
weekday -- 返回日期对象是周几。注意:返回值从0~6 ,也就是说MOnday== 0 ... Sunday == 6。
isoweekday --返回日期对象是周几,但是isoweekday 返回值与weekday的返回值不一样,其返回值范围为1~7:MOnday== 1 ... Sunday == 7。
>>> time.ctime()
'Wed Jul 9 11:24:58 2014' # 今天是周三
>>> today.weekday()
2 # 使用weekday 获取的返回值是2,因为它从0开始计数,周三对应2。
>>> today.isoweekday() # 使用isoweekday 获取的是3,符合日常使用习惯。
3
返回一个3元元组,值分别表示(年,第几周,周几)
>>> today.isocalendar()
(2014, 28, 3)
与time.strftime 类似,用于将时间对像进行格式化转化:
>>> today.strftime('%Y-%m-%d %H:%M:%S')
'2014-07-09 00:00:00' # 至此,我们才发现默认使用 today = datetime.date.today() 获取今天日期对象,只获取了日期信息,而对应的时间默认使用了 00:00:00,后面我们会介绍使用 datetime 对象将日期对象和时间对像结合!
注:下面介绍的对象中都会涉及到 strftime 或 strptime, 其实用法都和前面 time 模块中介绍的一样,具体参数意义也请参见《python 学习笔记 13 -- 常用的时间模块之time》
以时间结构体 struct_time 形式返回时间信息,与time.localtime()兼容:
>>> today.timetuple()
time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=190, tm_isdst=-1)
此函数能够解析time.time()返回的浮点值,返回一个datetime.date 日期值,格式为"datetime.date(2014, 7, 8)", 所以我们可以通过datetime.date.fromtimestamp(time.time()).year 来获取年(月,日亦可!)
>>> time.time()
1404876430.573843
>>> datetime.date.fromtimestamp(1404876430)
datetime.date(2014, 7, 9)
>>> datetime.date.fromtimestamp(1404876430.0)
datetime.date(2014, 7, 9)
>>> datetime.date.fromtimestamp(1404876430.0).year
2014
toordinal -- 返回日期对象位于公历的序数,也就是说返回值是“ 时间对象是从1年1月1日起的第几天”(返回值是一个整数)。
fromordinal -- 上面的toordinal 会将一个日期对象经过计算,返回这个日期是1年1月1日开始的第几天。而fromordinal 功能刚好与toordinal相反,它可以计算出一个给定的整形数对应的日期对象。
>>> today.toordinal()
735423
>>> datetime.date.fromordinal(735423)
datetime.date(2014, 7, 9)
0:00:00.000001
以 ISO 8601 格式(HH:MM:SS[.mmmmmm][+HH:MM].)返回时间值:
>>> ti.isoformat()与上面的日期类中的replace 方法类似,用于替换日期对象中的值:
>>> ti = datetime.time(15, 10, 20)如同上面的strftime 方法,以自定义的格式打印信息:
>>> ti.strftime('%Y-%m-%d %H:%M:%S')使用datetime 类可以存储由日期和时间分量构成的值。
我们先看看预定给datetime 类的一些细节:
>>> print datetime.datetime.resolution # 同time, datetime 的精度为一微秒
0:00:00.000001
>>> print datetime.datetime.min # datetime 最小值为0001年1月1日的0时0分0秒,这也是公历的起始
0001-01-01 00:00:00
>>> print datetime.datetime.max # 最大值
9999-12-31 23:59:59.999999
同上面date/time, datetime 也可以直接手动定义:" datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])" 其中year, month 以及day 参数是必需的。
>>> datetime.datetime(2008, 11, 20, 10, 50)
datetime.datetime(2008, 11, 20, 10, 50)
>>> print datetime.datetime(2008, 11, 20, 10, 50).time() # 可以直接使用time 和date 获取datetime 的时间和日期信息。
10:50:00
>>> print datetime.datetime(2008, 11, 20, 10, 50).time().hour # 想要获取时间/日期信息下面的时分秒/年月日就要在使用time/date 之后再使用需要的项来获取。
10
对于datetime 的十几种方法,我们按照官方手册将其分为“类方法”和“实例方法”两个方面来讲解:
类方法可以理解成通过 datetime.datetime.**() 调用的方法,如:
now = datetime.datetime.now()
=====================================================
today -- today 方法可以获取当前日期和时间(没有时区信息),等于datetime.datetime.fromtimestamp(time.time())。
now([tz]) -- 返回当前日期和时间,如果没有使用tz 作为参数,其结果与today方法一样;如果有时区信息,则返回的时区对应的时间(注:这里要求的tz 是tzinfo 类的一个实例而不是一个字符串)。
utcnow -- 方法与now 类似,只不过提供的是UTC 时间。(UTC,Coordinated Universal Time ,世界标准时间, now 得到的时间是根据UTC时间加上时区的)
>>> datetime.datetime.now()
datetime.datetime(2014, 7, 8, 20, 34, 59, 121292)
>>> datetime.datetime.today() # today 和now 获取的时间一致
datetime.datetime(2014, 7, 8, 20, 35, 0, 565851)
>>> datetime.datetime.utcnow() # UTC 时间当前为12点,而我们北京时间处于东8区,加8个小时,刚好等于now/today显示的20点
datetime.datetime(2014, 7, 8, 12, 35, 6, 89866)
fromtimestamp(timestamp[, tz]) -- fromtimestamp 根据POSIX 的时间戳(比如time.time())返回一个时间信息。与now 比较接近,如果没有携带'tz'参数,它会将时间戳转化为本地时间和日期;如果有时区信息'tz',返回的是该时区的时间信息。
utcfromtimestamp(timestamp) -- 将时间戳转化为UTC 时间
>>> datetime.datetime.utcfromtimestamp(time.time())
datetime.datetime(2014, 7, 9, 6, 42, 3, 395073)
>>> datetime.datetime.fromtimestamp(time.time()) # 本地时间,CST 比UTC时间多8小时
datetime.datetime(2014, 7, 9, 14, 42, 7, 528134)
>>> datetime.datetime.today() # 上面介绍today 时说了,today()的返回值与fromtimestamp(time.time())一样
datetime.datetime(2014, 7, 9, 14, 42, 19, 450996)
fromordinal -- 与下面要介绍的实例方法toordinal 相反,实例方法toordinal会将一个datetime 对象返回值为自公历1年1月1日起的第几天,而fromordinal 将一个天数(整形)计算出来对应的哪年哪月哪日。
>>> now
datetime.datetime(2014, 7, 8, 20, 41, 2, 882183)
>>> datetime.datetime.toordinal(now)
735422
>>> datetime.datetime.fromordinal(735422) # 因为toordinal 计算的只是第几天,未涉及到具体时间,所以fromordinal 转化后的时间为0:0:0
datetime.datetime(2014, 7, 8, 0, 0)
conbine 方法可以将一个date 实例和一个time 实例结合创建一个datetime 实例。
>>> today = datetime.date.today()
>>> today.strftime('%Y-%m-%d %H:%M:%S')
'2014-07-09 00:00:00' # 使用 date.today() 只会接收今天的日期,不会接收时间信息,时间默认使用 00:00:00
>>> now = datetime.time(12, 30, 00)
>>> now.strftime('%Y-%m-%d %H:%M:%S')
'1900-01-01 12:30:00' # 使用time 设置时间后,日期默认使用 1900-01-01
>>> print datetime.datetime.combine(today, now)
'2014-07-09 12:30:00' # 使用datetime 的combine 方法可以将上面的日期实例和时间实例集合为一个datetime 实例。
同前面介绍time 中的strptime一样,strptime 可以将一个格式化打印的字符串整合成为原来的datetime 对象。
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2014, 7, 9, 15, 54, 17, 742398)
>>> now.strftime('%Y-%m-%d %H:%M:%S') # 下面将要介绍的一个实例方法,其实和time.strftime 类似
'2014-07-09 15:54:17' # 此时是一个格式化打印的字符串\
>>> datetime.datetime.strptime(now.strftime('%Y-%m-%d %H:%M:%S'), '%Y-%m-%d %H:%M:%S')
datetime.datetime(2014, 7, 9, 15, 54, 17) # 使用strptime 将字符串还原为 datetime 对象
实例方法可以理解成datetime 实例/对象调用的方法,如:
now = datetime.datetime.now()
now.***(); ### 其中*** 对应的就是实例方法
其实也可以使用datetime.datetime.***(now)来调用。举个例子:
>>> now.date() # date 就是下面要讲的实例方法之一
datetime.date(2014, 7, 9)
>>> datetime.datetime.date(now) # 实例方法也可以通过类似于类方法那么调用,只不过需要实例/对象作为参数
datetime.date(2014, 7, 9)
既然放在实例方法一节,下面例子中都使用 now.***() 方式调用。
==============================================
返回datetime.datetime对象的日期值
>>> now = datetime.datetime.now()
>>> now.date()
datetime.date(2014, 7, 9)
time --将一个datetime.datetime 对象的时间值返回
timetz -- 使用相同的时间和时区返回time 对象
>>> now.time()
datetime.time(14, 48, 2, 224132)
>>> now.timetz()
datetime.time(14, 48, 2, 224132)
可以指定修改域对datetime 实例进行修改:
>>> utcnow = datetime.datetime.utcnow()
>>> utcnow
datetime.datetime(2014, 7, 8, 12, 37, 21, 59472)
>>> utcnow.replace(hour = 1)
datetime.datetime(2014, 7, 8, 1, 37, 21, 59472)
timetuple --将一个datetime.datetime 对象解析成一个struc_time结构体返回。(与time.localtime()的返回值类型一样)
utctimetuple -- 与上面timetuple类似,返回UTC时间的解析结构体
>>> now.timetuple()
time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=48, tm_sec=2, tm_wday=2, tm_yday=190, tm_isdst=-1)
>>> now.utctimetuple()
time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=48, tm_sec=2, tm_wday=2, tm_yday=190, tm_isdst=0)
>>> time.localtime(time.time()) # 使用time.localtime 解析time()的浮点数得到的结果同timetuple 一样,都是struct_time 结构的时间
time.struct_time(tm_year=2014, tm_mon=7, tm_mday=9, tm_hour=14, tm_min=51, tm_sec=12, tm_wday=2, tm_yday=190, tm_isdst=0)
返回一个整数,代表datetime.datetime 对象是从第1年第1月第1天算起的第几天。
weekday -- 返回datetime对象是周几,但是对应的值从0~6: MOnday== 0 ... Sunday == 6
isoweekday -- 返回datetime对象是周几,对应的值从1~7: MOnday== 1 ... Sunday == 7
>>> now.ctime() # 以ctime() 字符串形式打印datetime 对象的时间日期信息。下面会提到
'Wed Jul 9 14:48:02 2014' # 周三
>>> now.weekday()
2 # 周三使用weekday 返回2
>>> now.isoweekday()
3 # isoweekday 返回3
返回一个三值的元组,格式为(年,第几周,周几)
>>> now.isocalendar()
(2014, 28, 3)
以ISO 8601 格式(YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM])打印datetime.datetime对象。默认使用的间隔符是'T'.
>>> datetime.datetime.isoformat(now)
'2014-07-08T20:41:02.882183'
ctime -- 将datetime.datetime 对象解析成time.ctime 的字符串
strftime -- 同其他类一样,datetime 可以通过strftime 进行格式化打印成你想要的格式。(默认是用的是ISO-8601 格式:YYYY-MM-DDTHH:MM:SS.mmmmmm)
>>> now.strftime('%Y-%m-%d %H:%M:%S')
'2014-07-09 14:48:02'
上面还未涉及到这几个函数astimezone, utcoffset, dst, tzname,都是与时区相关,一般涉及不到,此处不追逐。
datetime 对象之间可以使用算术运算,或者结合一个datetime 和一个timedelta ,可以用来计算过去或将来的一些日期。两个日期相减可以生成一个timedelta, 还可以对某个日期与一个timedelta 计算来得出另一个日期。所以可以理解成两个datetime 的中间变量,可以用于计算和比较。
来看看timedelta 的精度以及范围:
>>> print datetime.timedelta.max
999999999 days, 23:59:59.999999
>>> print datetime.timedelta.min
-999999999 days, 0:00:00
>>> print datetime.timedelta.resolution # 精度为1微秒
0:00:00.000001
timedelta 的内部值按日、秒和毫秒存储:
>>> td = datetime.timedelta(microseconds = 1); print "%s -- %r" %(td, td)
0:00:00.000001 -- datetime.timedelta(0, 0, 1)
>>> td = datetime.timedelta(milliseconds = 1); print "%s -- %r" %(td, td)
0:00:00.001000 -- datetime.timedelta(0, 0, 1000)
>>> td = datetime.timedelta(seconds = 1); print "%s -- %r" %(td, td)
0:00:01 -- datetime.timedelta(0, 1)
>>> td = datetime.timedelta(minutes = 1); print "%s -- %r" %(td, td)
0:01:00 -- datetime.timedelta(0, 60)
>>> td = datetime.timedelta(hours = 1); print "%s -- %r" %(td, td)
1:00:00 -- datetime.timedelta(0, 3600)
>>> td = datetime.timedelta(days = 1); print "%s -- %r" %(td, td)
1 day, 0:00:00 -- datetime.timedelta(1)
>>> td = datetime.timedelta(weeks = 1); print "%s -- %r" %(td, td)
7 days, 0:00:00 -- datetime.timedelta(7)
因为timedelta 只是一个用于计算的中间量,所以并没有提供很多方法,用apihelper 可以看到只提供一个方法total_seconds 用以返回一个timedelta 完整时间段的所有秒数:
>>> td = datetime.timedelta(hours = 1); print td.total_seconds()
3600.0
>>> one_day = datetime.timedelta(days = 1); # one_day 是一个定义为1天的timedelta 实例
>>> today = datetime.date.today() # today 是date 实例
>>> tomorrow = today + one_day # 直接使用timedelta 实例与datetime 的date 实例进行计算
>>> yestoday = today - one_day
>>> today
datetime.date(2014, 7, 8)
>>> tomorrow
datetime.date(2014, 7, 9)
>>> yestoday
datetime.date(2014, 7, 7)
>>> tomorrow - yestoday # 两个date 实例也可以计算
datetime.timedelta(2)
>>> print tomorrow - yestoday
2 days, 0:00:00
>>> today > yestoday # date 实例可以直接比较
True
>>> tomorrow == yestoday
False