当前位置: 首页 > 文档资料 > 跟老齐学 Python >

标准库(5)

优质
小牛编辑
130浏览
2023-12-01

凡所行的,都不要发怨言、起争论,使你们无可指摘,诚实无伪,在这弯曲悖谬的世代作神无瑕疵的儿女。你们显在这世代中,好像明光照耀,将生命的道表明出来。(PHILIPPIANS 2:14-15)

标准库(5)

“一寸光阴一寸金,寸金难买寸光阴”,时间是宝贵的。

在日常生活中,“时间”这个术语是比较笼统和含糊的。在物理学中,“时间”是一个非常明确的概念。在Python中,“时间”可以通过相关模块实现。

calendar

>>> import calendar>>> cal = calendar.month(2015, 1)>>> print cal    January 2015Mo Tu We Th Fr Sa Su          1  2  3  4 5  6  7  8  9 10 1112 13 14 15 16 17 1819 20 21 22 23 24 2526 27 28 29 30 31

轻而易举得到了2015年1月的日历,并且排列的还那么整齐。这就是calendar模块。读者可以用dir()去查看这个模块下的所有内容。为了让读者阅读方便,将常用的整理如下:

calendar(year,w=2,l=1,c=6)

返回year年的年历,3个月一行,间隔距离为c。 每日宽度间隔为w字符。每行长度为21* w+18+2* c。l是每星期行数。

>>> year = calendar.calendar(2015)>>> print year                                  2015      January                   February                   MarchMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su          1  2  3  4                         1                         1 5  6  7  8  9 10 11       2  3  4  5  6  7  8       2  3  4  5  6  7  812 13 14 15 16 17 18       9 10 11 12 13 14 15       9 10 11 12 13 14 1519 20 21 22 23 24 25      16 17 18 19 20 21 22      16 17 18 19 20 21 2226 27 28 29 30 31         23 24 25 26 27 28         23 24 25 26 27 28 29                                                    30 31       April                      May                       JuneMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su       1  2  3  4  5                   1  2  3       1  2  3  4  5  6  7 6  7  8  9 10 11 12       4  5  6  7  8  9 10       8  9 10 11 12 13 1413 14 15 16 17 18 19      11 12 13 14 15 16 17      15 16 17 18 19 20 2120 21 22 23 24 25 26      18 19 20 21 22 23 24      22 23 24 25 26 27 2827 28 29 30               25 26 27 28 29 30 31      29 30        July                     August                  SeptemberMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su       1  2  3  4  5                      1  2          1  2  3  4  5  6 6  7  8  9 10 11 12       3  4  5  6  7  8  9       7  8  9 10 11 12 1313 14 15 16 17 18 19      10 11 12 13 14 15 16      14 15 16 17 18 19 2020 21 22 23 24 25 26      17 18 19 20 21 22 23      21 22 23 24 25 26 2727 28 29 30 31            24 25 26 27 28 29 30      28 29 30                          31      October                   November                  DecemberMo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su      Mo Tu We Th Fr Sa Su          1  2  3  4                         1          1  2  3  4  5  6 5  6  7  8  9 10 11       2  3  4  5  6  7  8       7  8  9 10 11 12 1312 13 14 15 16 17 18       9 10 11 12 13 14 15      14 15 16 17 18 19 2019 20 21 22 23 24 25      16 17 18 19 20 21 22      21 22 23 24 25 26 2726 27 28 29 30 31         23 24 25 26 27 28 29      28 29 30 31                          30

其它部分就是按照上面的样式,将2015年度的各个月份日历完全显示出来。

isleap(year)

判断是否为闰年,是则返回true,否则false.

>>> calendar.isleap(2000)True>>> calendar.isleap(2015)False

怎么判断一年是闰年,常常见诸于一些编程语言的练习题,现在用一个方法搞定。

leapdays(y1, y2)

返回在y1,y2两年之间的闰年总数,包括y1,但不包括y2,这有点如同序列的切片一样。

>>> calendar.leapdays(2000, 2004)1>>> calendar.leapdays(2000, 2003)1

month(year, month, w=2, l=1)

返回year年month月日历,两行标题,一周一行。每日宽度间隔为w字符。每行的长度为7* w+6,l是每星期的行数。

>>> print calendar.month(2015, 5)      May 2015Mo Tu We Th Fr Sa Su             1  2  3 4  5  6  7  8  9 1011 12 13 14 15 16 1718 19 20 21 22 23 2425 26 27 28 29 30 31

monthcalendar(year,month)

返回一个列表,列表内的元素还是列表。每个子列表代表一个星期,都是从星期一到星期日,如果没有本月的日期,则为0。

>>> calendar.monthcalendar(2015, 5)[[0, 0, 0, 0, 1, 2, 3], [4, 5, 6, 7, 8, 9, 10], [11, 12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23, 24], [25, 26, 27, 28, 29, 30, 31]]

读者可以将这个结果和calendar.month(2015, 5)去对照理解。

monthrange(year, month)

返回一个元组,里面有两个整数。第一个整数代表着该月的第一天从星期几是(从0开始,依次为星期一、星期二,直到6代表星期日)。第二个整数是该月一共多少天。

>>> calendar.monthrange(2015, 5)(4, 31)

从返回值可知,2015年5月1日是星期五,这个月一共31天。这个结果,也可以从日历中看到。

weekday(year,month,day)

输入年月日,知道该日是星期几(注意,返回值依然按照从0到6依次对应星期一到星期六)。

>>> calendar.weekday(2015, 5, 4)    #星期一0>>> calendar.weekday(2015, 6, 4)    #星期四3

time

time()

time模块很常用,比如记录某个程序运行时间的长短等,下面一一道来其中的方法。

  • time()

    import timetime.time() 1430745298.391026

time.time()获得的是当前时间(严格说是时间戳),只不过这个时间对人不友好,它是以1970年1月1日0时0分0秒为计时起点,到当前的时间长度(不考虑闰秒)。

UNIX時間,或稱POSIX時間是UNIX或類UNIX系統使用的時間表示方式:從協調世界時1970年1月1日0時0分0秒起至現在的總秒數,不考慮閏秒

現時大部分使用UNIX的系統都是32位元的,即它們會以32位二進制數字表示時間。但是它們最多只能表示至協調世界時間2038年1月19日3時14分07秒(二進制:01111111 11111111 11111111 11111111,0x7FFF:FFFF),在下一秒二進制數字會是10000000 00000000 00000000 00000000,(0x8000:0000),這是負數,因此各系統會把時間誤解作1901年12月13日20時45分52秒(亦有說回歸到1970年)。這時可能會令軟體發生問題,導致系統癱瘓。

目前的解決方案是把系統由32位元轉為64位元系統。在64位系統下,此時間最多可以表示到292,277,026,596年12月4日15時30分08秒。

有没有对人友好一点的时间显示呢?

localtime()

>>> time.localtime()time.struct_time(tm_year=2015, tm_mon=5, tm_mday=4, tm_hour=21, tm_min=33, tm_sec=39, tm_wday=0, tm_yday=124, tm_isdst=0)

这个就友好多了。得到的结果可以称之为时间元组(也有括号),其各项的含义是:

索引属性含义
0tm_year
1tm_mon
2tm_mday
3tm_hour
4tm_min
5tm_sec
6tm_wday一周中的第几天
7tm_yday一年中的第几天
8tm_isdst夏令时
>>> t = time.localtime()>>> t[1]5

通过索引能够得到相应的属性,上面的例子中就得到了当前时间的月份。

其实,time.localtime()不是没有参数,它在默认情况下,以time.time()的时间戳为参数。言外之意就是说可以自己输入一个时间戳,返回那个时间戳所对应的时间(按照公元和时分秒计时)。例如:

>>> time.localtime(100000)time.struct_time(tm_year=1970, tm_mon=1, tm_mday=2, tm_hour=11, tm_min=46, tm_sec=40, tm_wday=4, tm_yday=2, tm_isdst=0)

gmtime()

localtime()得到的是本地时间,如果要国际化,就最好使用格林威治时间。可以这样:

>>> import time>>> time.gmtime()time.struct_time(tm_year=2015, tm_mon=5, tm_mday=4, tm_hour=23, tm_min=46, tm_sec=34, tm_wday=0, tm_yday=124, tm_isdst=0)

格林威治標準時間(中國大陸翻譯:格林尼治平均時間或格林尼治標準時間,台、港、澳翻譯:格林威治標準時間;英语:Greenwich Mean Time,GMT)是指位於英國倫敦郊區的皇家格林威治天文台的標準時間,因為本初子午線被定義在通過那裡的經線。

还有更友好的,请继续阅读。

asctime()

>>> time.asctime()'Mon May  4 21:46:13 2015'

time.asctime()的参数为空时,默认是以time.localtime()的值为参数,所以得到的是当前日期时间和星期。当然,也可以自己设置参数:

>>> h = time.localtime(1000000)>>> htime.struct_time(tm_year=1970, tm_mon=1, tm_mday=12, tm_hour=21, tm_min=46, tm_sec=40, tm_wday=0, tm_yday=12, tm_isdst=0)>>> time.asctime(h)'Mon Jan 12 21:46:40 1970'

注意,time.asctime()的参数必须是时间元组,类似上面那种。不是时间戳,通过time.time()得到的时间戳也可以转化为上面形式。

ctime()

>>> time.ctime()'Mon May  4 21:52:22 2015'

在没有参数的时候,事实上是以time.time()的时间戳为参数。也可以自定义一个时间戳。

>>> time.ctime(1000000)'Mon Jan 12 21:46:40 1970'

跟前面得到的结果是一样的,只不过用了时间戳作为参数。

在前述函数中,通过localtime()gmtime()得到的是时间元组,通过time()得到的是时间戳。有的函数如asctime()是以时间元组为参数,有的如ctime()是以时间戳为参数,这样做的目的是为了满足编程中多样化的需要。

mktime()

mktime()也是以时间元组为参数,但是它返回的不是可读性更好的那种样式,而是:

>>> lt = time.localtime()>>> lttime.struct_time(tm_year=2015, tm_mon=5, tm_mday=5, tm_hour=7, tm_min=55, tm_sec=29, tm_wday=1, tm_yday=125, tm_isdst=0)>>> time.mktime(lt)1430783729.0

返回了时间戳。就类似于localtime()的逆过程(localtime()是以时间戳为参数)。

好像还缺点什么,因为在编程中,用的比较多的是“字符串”,似乎还没有将时间转化为字符串的函数。这个应该有。

strftime()

函数格式稍微复杂一些。

Help on built-in function strftime in module time:strftime(...)    strftime(format[, tuple]) -> string    Convert a time tuple to a string according to a format specification.    See the library reference manual for formatting codes. When the time tuple    is not present, current time as returned by localtime() is used.

将时间元组按照指定格式要求转化为字符串。如果不指定时间元组,就默认为localtime()值。说复杂,是在于其format,需要用到下面的东西。

格式含义取值范围(格式)
%y去掉世纪的年份00-99,如"15"
%Y完整的年份如"2015"
%j指定日期是一年中的第几天001-366
%m返回月份01-12
%b本地简化月份的名称简写英文月份
%B本地完整月份的名称完整英文月份
%d该月的第几日如5月1日返回"01"
%H该日的第几时(24小时制)00-23
%l该日的第几时(12小时制)01-12
%M分钟00-59
%S00-59
%U在该年中的第多少星期(以周日为一周起点)00-53
%W同上,只不过是以周一为起点00-53
%w一星期中的第几天0-6
%Z时区在中国大陆测试,返回CST,即China Standard Time
%x日期日/月/年
%X时间时:分:秒
%c详细日期时间日/月/年 时:分:秒
%%‘%’字符‘%’字符
%p上下午AM or PM

简要列举如下:

>>> time.strftime("%y,%m,%d")'15,05,05'>>> time.strftime("%y/%m/%d")'15/05/05'

分隔符可以自由指定。既然已经变成字符串了,就可以“随心所欲不逾矩”了。

strptime()

Help on built-in function strptime in module time:strptime(...)    strptime(string, format) -> struct_time    Parse a string to a time tuple according to a format specification.    See the library reference manual for formatting codes (same as strftime()).

strptime()的作用是将字符串转化为时间元组。

请注意的是,其参数要指定两个,一个是时间字符串,另外一个是时间字符串所对应的格式,格式符号用上表中的。例如:

>>> today = time.strftime("%y/%m/%d")>>> today'15/05/05'>>> time.strptime(today, "%y/%m/%d")time.struct_time(tm_year=2015, tm_mon=5, tm_mday=5, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=125, tm_isdst=-1)

datetime

虽然time模块已经能够把有关时间方面的东西搞定了,但是,有时调用起来感觉不是很直接,于是又出来了一个datetime模块,供程序猿和程序媛们选择使用。

datetime模块中有几个类:

  • datetime.date:日期类,常用的属性有year/month/day
  • datetime.time:时间类,常用的有hour/minute/second/microsecond
  • datetime.datetime:日期时间类
  • datetime.timedelta:时间间隔,即两个时间点之间的时间长度
  • datetime.tzinfo:时区类

date

通过实例了解常用的属性:

>>> import datetime>>> today = datetime.date.today()>>> todaydatetime.date(2015, 5, 5)

其实这里生成了一个日期对象,然后操作这个对象的各种属性。可以用print,以获得更佳视觉:

>>> print today        #Python 3: print(today)2015-05-05>>> print today.ctime()        #Python 3: print(today.ctime())Tue May  5 00:00:00 2015>>> print today.timetuple()        #Python 3: print(today.timetuple())time.struct_time(tm_year=2015, tm_mon=5, tm_mday=5, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=125, tm_isdst=-1)>>> print today.toordinal()        #Python 3: print(today.toordinal())735723

特别注意,如果你妄图用datetime.date.year(),是会报错的,因为year不是一个方法,必须这样行:

>>> print today.year2015>>> print today.month5>>> print today.day5

进一步看看时间戳与格式化时间格式的转换

>>> to = today.toordinal()>>> to735723>>> print datetime.date.fromordinal(to)2015-05-05>>> import time>>> t = time.time()>>> t1430787994.80093>>> print datetime.date.fromtimestamp(t)2015-05-05

还可以更灵活一些,修改日期。

>>> d1 = datetime.date(2015,5,1)>>> print d12015-05-01>>> d2 = d1.replace(year=2005, day=5)>>> print d22005-05-05

time类

也要生成time对象

>>> t = datetime.time(1,2,3)>>> print t01:02:03

它的常用属性:

>>> print t.hour1>>> print t.minute2>>> print t.second3>>> t.microsecond0>>> print t.tzinfoNone

timedelta类

主要用来做时间的运算。比如:

>>> now = datetime.datetime.now()>>> print now        #Python 3: print(now)2015-05-05 09:22:43.142520

没有讲述datetime类,因为在有了date和time类知识之后,这个类比较简单。

now增加5个小时;

>>> b = now + datetime.timedelta(hours=5)>>> print b        #Python 3: print(b)2015-05-05 14:22:43.142520

增加两周;

>>> c = now + datetime.timedelta(weeks=2)>>> print c        #Python 3: print(c)2015-05-19 09:22:43.142520

计算时间差:

>>> d = c - b>>> print d        #Python 3: print(d)13 days, 19:00:00