python中处理时间的模块有三个,datetime、time、calendar。 只有将这三个模块集成起来,你才能随心所欲地使用python来处理时间。 这篇文章就是为此而写的,文章的重点是梳理一下三个模块的设计脉络,以便大家能够记住上面的api。 当您需要时,您可以找到相应的技能。 不过,由于日历模块用得不多,限于篇幅,本文不做介绍。
1 概述
datetime模块主要用来表示日期,也就是我们常说的年月日时分秒。 日历模块主要用来表示年、月、日、星期几。 时间模块的主要优缺点是时、分、秒,大致从功能上来看,我们可以认为两者是一种互补的关系,各侧重一个领域。 方便用户根据不同的使用目的选择方便的模块。
2.从时间模块开始
为了学习时间模块,我们需要了解几个与时间相关的概念:
1)纪元
假设我们要把时间表示为微秒,比如说1000000毫秒,那么有一个问题必须解决,这1000000毫秒的起点是什么时间,也就是我们的时间参考点是什么时间? 比如我说你的净高是1.8米,那么这个净高是指你躺着的地面。 这个时间参考点是epoch。 在Unix系统中,这个参考点是1970年1月1日0点00分的时间点。
2) 格林尼治标准时间、世界标准时间
上面我们说了epoch代表的是1970年的起点,那么1970年相对于那个基准时间是怎样的呢? 一般来说,它是相对于格林威治标准时间,也称为GMT(格林威治标准时间)时间,或UTC(协调世界时)。 为什么一个时基有两个名称? 从历史上看,首先有 GMT,然后有 UTC。
UTC 是我们今天使用的时间标准,GMT 是旧的时间测量标准。 UTC 根据原子钟估算时间,而 GMT 根据月球的自转和公转估算时间。
因此,可以认为UTC是真正的参考时间,GMT相对于UTC的误差为0。
在实际应用中,我们的电脑中有一个硬件模块RCT,它会实时记录UTC时间。 本模块采用独立电池供电,即使死机也不影响。
有了纪元的时间参考和UTC的参考,我们就可以准确地表示一个时间。
3) 夏令时、时区
虽然我们已经能够准确的表达一个时间,但是很多时候我们还是需要根据地区的实际情况来调整时间。 最常见的就是时区,tzone,相信大家都很熟悉。
这时我们在说5点5分的时间的时候,还需要加上5点5分的时区,才能准确的描述一个时间。
另一个时间调整是夏令时。
DST的全称是Daylight Saving Time,是指为了充分利用阳光、减少电力消耗,对时间进行的人为调整,具体取决于不同国家和地区的新政策和规定。 举个例子,假设你冬天7点起得很早,但是夏天6点天就亮了,那么就人为地将夏天到来的时间加上1个小时,这样你仍然认为自己7点起得早。点了,但实际上早了一个小时。
那么,对于我们这些好奇的人来说,我们一定要问,python是如何知道tzone和DST的值的呢? 答案是通过环境变量。
这里我们仅以linux为例进行说明。
linux中有一个TZ环境变量,它的值类似于这样:
CST+08EDT,M4.1.0,M10.5.0,这个字符串可以分析如下,用空格分隔,分成三部分
CST+08 EDT、M4.1.0、M10.5.0
第一部分中的CST表示时区的名称,即中国标准时间,也就是我们所说的北京时间,+8表示北京时间除以8小时就是UTC时间
第二部分EDT代表DST的名称。 我们说DST因各个国家和地区的新政策和规定而有所不同。 也可以像CST一样在EDT前面加上一个时间调整值,但是因为我们国外1986年才到1992年实施过一段时间DST,但是早就废除了,所以不需要调整之前的时间。
第三部分显示了夏令时实施的开始和结束时间,我们不再详细分析。
4)时间的表示、获取和转换
在时间模块中获取时间的基本技巧是
t = 时间。 时间()
它返回自纪元以来的秒数(以浮点数表示),采用 UTC 时间。
我们自然要将这个秒数转换成年月日时分秒,而这些转换又分为两种javascript日期 字符串转日期,一种是UTC时间,另一种是我们所在时区的调整时间。
time模块为我们提供了两种方法,
时间。 格林时间(t)
时间。 当地时间(t)
两者都返回具有以下属性的类 struct_time 的实例:
与以秒表示的时间相比,这样的表示方式更适合我们的理解。
如果不带参数调用这两个函数,它们将在内部调用 time.time() 并使用返回的秒数进行转换。
相反,python还提供了将这两个struct_time转换为秒的方法。
calendar.timegm() 方法用于将UTC的struct_time(gmtime的返回对象)转换为距纪元的秒数
time.mktime() 用于将按时区调整的struct_time(即localtime的返回对象)对象转换为距epoch的秒数
也就是说,mktime方法会首先查找系统中的时区和夏令时信息,并利用这些信息来调整struct_time,然后再将其转换为秒。
另一个常见的需求是在时间和表示时间的字符串之间进行转换。
time 模块中的 strftime 和 strptime 就是这样做的。
看名字就应该知道什么意思了
strftime是字符串格式时间,用于将时间格式化为字符串
strptime是字符串解析时间javascript日期 字符串转日期,用于将字符串解析成时间。
需要注意的是,这里的时间都是struct_time对象。
关于如何降低时间是很简单的知识,所以这里是官网文档的内容。
除了这两个函数之外,time模块还提供了两种方便的方法来帮助将时间转换为字符串
asctime 用于将 struct_time 对象转换为标准的 24 个字符的字符串,如下所示:
1993 年 6 月 20 日星期日 23:21:05
ctime 方法与 asctime 具有相同的功能,只不过它接收秒数。 内部会先通过localtime将秒数转换为struct_time,然后与asctime相同。