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

书接上文,前面我们讲到《常用的时间模块之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)  toordinalfromordinal

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



python 学习笔记 14 -- 常用的时间模块之datetime,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。