您的位置:首页 > 编程语言 > Python开发

python 学习笔记 14 -- 常用的时间模块之datetime

2014-07-09 16:10 1286 查看
书接上文,前面我们讲到《常用的时间模块之time》,这次我们学习datetime
-- 日期和时间值管理模块

使用apihelper 查看datetime 模块,我们可以看到简单的几项:

date --- 日期对象,结构为date(year, month, day)

time --- 时间值对象,结构为 time([hour[, minute[, second[, microsecond[, tzinfo]]]]])。时间对象所有的参数都是可选的。tzinfo 可以是None 或者是tzinfo子类的一个实例。

datetime --- 日期和时间管理对象,结构为 datetime(year, month, day[, hour[, minute[, second[, microsecond[,tzinfo]]]]])。 其中year, month 以及day 参数是必需的。而tzinfo 可以是None 或者是tzinfo子类的一个实例。

timedelta --- 两个datetime 值的差。用作datetime 对象之间的计算以及比较。

tzinfo --- 时区信息对象的抽象基类。



我们可以看到datetime 模块下面还有好几个具体的类,下面分别从这几个类来分析datetime 模块:

1. date

1.1 date 类简介以及简单使用

date 是一个日期对象类,它有year,month和day三个属性。使用today()方法很容易创建一个表示当前日期的日期对象。当然,我们也可以手动指定年月日,从而直接使用datetime.date(year, month, day) 来创建一个日期对象,如:

>>> da = datetime.date(1991, 1, 1)

>>> da

datetime.date(1991, 1, 1)

>>> da.year # 还可以通过指定具体项获取对应值

1991

我们再来看看date 类的相关信息:

>>> print datetime.date.resolution # 日期对象的分辨率是一天

1 day, 0:00:00

>>> print datetime.date.min # 日期对象最小值是1-1-1,下面会提到 toordinal 函数,它的返回值就是从这天计算的

0001-01-01

>>> print datetime.date.max # 最大值

9999-12-31

date 对象之间是可以计算的,算算你到这个世界多久了?

>>> bron_day = datetime.date(1991, 1, 1) # 指定生日

>>> today = datetime.date.today() # 获取今天的date 信息

>>> print today-bron_day

8590 days, 0:00:00 # date 对象之间直接相减,得到以日计算的差值

>>> today < bron_day

False # 还可以直接对date 对象进行比较

1.2 date 类提供的方法

下面我们仍然使用apihelper (使用见《python 学习笔记 9 -- Python强大的自省简析》)来查看date 类还提供了哪些强大的方法:

(1) today

以当前时间获取一个日期对象

>>> today = datetime.date.today()

>>> today

datetime.date(2014, 7, 8)

(2) ctime

将一个日期对象转化为ctime() 形式的字符串

>>> date.date.ctime(today)

'Tue Jul 8 00:00:00 2014'

(3) replace

对于日期对象,支持使用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

(4) isoformat

以ISO 8601 格式("YYYY-MM-DD")返回一个日期对象:

>>> datetime.date.isoformat(today)

'2014-07-08'

(5) weekday 和 isoweekday

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

(6) isocalendar

返回一个3元元组,值分别表示(年,第几周,周几)

>>> today.isocalendar()

(2014, 28, 3)

(7) strftime

与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

(8) timetuple

以时间结构体 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)

(9) fromtimestamp

此函数能够解析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

(10) toordinal 和fromordinal

toordinal --
返回日期对象位于公历的序数,也就是说返回值是“ 时间对象是从1年1月1日起的第几天”(返回值是一个整数)。

fromordinal -- 上面的toordinal 会将一个日期对象经过计算,返回这个日期是1年1月1日开始的第几天。而fromordinal 功能刚好与toordinal相反,它可以计算出一个给定的整形数对应的日期对象。

>>> today.toordinal()

735423

>>> datetime.date.fromordinal(735423)

datetime.date(2014, 7, 9)

2. time

2.1 time 类简介以及简单使用

datetime 的 time类用来表示时间信息,如上面介绍的date 类,我们可以使用time([hour[, minute[, second[, microsecond[, tzinfo]]]]]) 来初始化时间对象。

我们再来看看time 类的相关信息:

>>> print datetime.time.min # 合法时间范围为00:00:00 ~ 23:59:59.999999

00:00:00

>>> print datetime.time.max

23:59:59.999999

>>> print datetime.time.resolution # 分辨率限制为微秒级

0:00:00.000001

我们也可以直接指定项获取其内容:

>>> ti = datetime.time(11, 36, 0)

>>> ti.hour

11

2.2 time 类提供的方法

下面我们仍然使用apihelper来查看time 类提供了哪些强大的方法:

(1) isoformat

以 ISO 8601 格式(HH:MM:SS[.mmmmmm][+HH:MM].)返回时间值:

>>> ti.isoformat()

'15:10:20'

(2) replace

与上面的日期类中的replace 方法类似,用于替换日期对象中的值:

>>> ti = datetime.time(15, 10, 20)

>>> ti.replace(hour = 12)

datetime.time(12, 10, 20)

(3) strftime

如同上面的strftime 方法,以自定义的格式打印信息:

>>> ti.strftime('%Y-%m-%d %H:%M:%S')

'1900-01-01 15:10:20' # 看来未指定年月日,系统默认是1900-01-01

其他还有三个方法: dst, tzname, utcoffset ,一般应该用不上,这里就不介绍了!

3. datetime

3.1 datetime 类简介以及简单使用

使用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 的十几种方法,我们按照官方手册将其分为“类方法”和“实例方法”两个方面来讲解:

3.2 类方法:

类方法可以理解成通过 datetime.datetime.**() 调用的方法,如:

now = datetime.datetime.now()

=====================================================

(1) today, now 和 utcnow

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)

(2) fromtimestamp 和 utcfromtimestamp

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)

(3) fromordinal

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)

(4) combine

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 实例。

(5) strptime

同前面介绍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 对象

3.3 实例方法:

实例方法可以理解成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.***() 方式调用。

==============================================

(1)date

返回datetime.datetime对象的日期值

>>> now = datetime.datetime.now()

>>> now.date()

datetime.date(2014, 7, 9)

(2) time 和 timetz

time --将一个datetime.datetime 对象的时间值返回

timetz -- 使用相同的时间和时区返回time 对象

>>> now.time()

datetime.time(14, 48, 2, 224132)

>>> now.timetz()

datetime.time(14, 48, 2, 224132)

(3) replace

可以指定修改域对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)

(4) timetuple 和 utctimetuple

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)

(5) toordinal

返回一个整数,代表datetime.datetime 对象是从第1年第1月第1天算起的第几天。

(6) weekday 和 isoweekday

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

(7) isocalendar

返回一个三值的元组,格式为(年,第几周,周几)

>>> now.isocalendar()

(2014, 28, 3)

(8) isoformat

以ISO 8601 格式(YYYY-MM-DDTHH:MM:SS[.mmmmmm][+HH:MM])打印datetime.datetime对象。默认使用的间隔符是'T'.

>>> datetime.datetime.isoformat(now)

'2014-07-08T20:41:02.882183'

(9) ctime

ctime -- 将datetime.datetime 对象解析成time.ctime 的字符串

(10) strftime

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'

(11) 其他

上面还未涉及到这几个函数astimezone, utcoffset, dst, tzname,都是与时区相关,一般涉及不到,此处不追逐。



4. timedelta

4.1 timedelta 类简介以及简单使用

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)

4.2 timedelta 类提供的方法

因为timedelta 只是一个用于计算的中间量,所以并没有提供很多方法,用apihelper 可以看到只提供一个方法total_seconds 用以返回一个timedelta 完整时间段的所有秒数:

>>> td = datetime.timedelta(hours = 1); print td.total_seconds()

3600.0

4.3 使用timedelta 计算

>>> 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

4.4 使用timedelta 比较

>>> today > yestoday # date 实例可以直接比较

True

>>> tomorrow == yestoday

False

写到这,感觉该有的都有了,而且本文中有大量的例子,其实如果你不练习,还是难以记住这么多知识点,只要亲自写代码试验了,这些还是很好记很好理解的。比如说你可以做一个小闹钟提示什么的。

==================================

说在最后的话:

其实悉心的你可以发现,datetime 类中还有 tzinfo 没有介绍,但是~~说实话,没怎么看懂,而且应该也用不上。此处不再赘述,还望谅解。

=======================================

注:本文介绍了 datetime 模块,其他的时间模块还有 time 和calendar 将于本系列其他文章。绝大部分内容都取自《Python 标准库》以及Python 官方文档,
限于个人能力有限,如有解释错误或者不当,敬请提出~

注: 转载注明出处: http://blog.csdn.net/longerzone
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: