摘要:关于python中的datetime模块和time模块的使用。

time模块

在 Python 文档里,time是归类在Generic Operating System Services中,换句话说, 它提供的功能是更加接近于操作系统层面的。通读文档可知,time 模块是围绕着 Unix Timestamp 进行的。

该模块主要包括一个类 struct_time,另外其他几个函数及相关常量。 需要注意的是在该模块中的大多数函数是调用了所在平台C library的同名函数, 所以要特别注意有些函数是平台相关的,可能会在不同的平台有不同的效果。另外一点是,由于是基于Unix Timestamp,所以其所能表述的日期范围被限定在 1970 - 2038 之间,如果你写的代码需要处理在前面所述范围之外的日期,那可能需要考虑使用datetime模块更好。文档解释比较费劲,具体看看怎么用:

time模块的主要使用的两个方法一个是time.sleep(5)休眠五秒。另一个是time.time()取当前的Unix Timestamp

关于时间的两个概念
UTC时间: 协调世界时。和GMT(格林尼治平均时间)是一个东西,只不过UTC是通过原子钟测量出来,GMT是通过天文观测出来的,所以UTC比GMT精度更高,因此现在世界上不同时区的时间都是以UTC时间为基准,如:北京时间=UTC时间+8小时

DST: 夏时令(daylight saving time),因为夏天天亮的早,所以有的国家就在一年的某些时段把时间人为的调快一小时,使人们早睡,减少照明亮,充分利用光照资源,从而节约能源。我国也实行过,不过后来废止了。

>>> import time 
>>> time.time()
1606055465.703837

>>> timestamp = time.time()
>>> time.gmtime(timestamp) # 接受时间戳,返回一个时间元组,表示当前格林尼治平均时间
time.struct_time(tm_year=2020, tm_mon=11, tm_mday=22, tm_hour=14, tm_min=33, tm_sec=40, tm_wday=6, tm_yday=327, tm_isdst=0)

>>> time.localtime(timestamp) # 接受时间戳,返回一个时间元组,表示自己本地计算机显示的时间
time.struct_time(tm_year=2020, tm_mon=11, tm_mday=22, tm_hour=22, tm_min=33, tm_sec=40, tm_wday=6, tm_yday=327, tm_isdst=0)
>>> time.localtime(timestamp)[0]
2020
>>> time.localtime() # 没有参数,则默认以当前时间的时间戳为参数
time.struct_time(tm_year=2020, tm_mon=11, tm_mday=22, tm_hour=22, tm_min=50, tm_sec=38, tm_wday=6, tm_yday=327, tm_isdst=0)

>>> time.ctime(timestamp) # 接受时间戳浮点数,转换成易读的字符串
'Sun Nov 22 22:33:40 2020'

>>> time.ctime() # 没有参数,则默认以当前时间的时间戳为参数,相当于time.asctime(localtime())
'Sun Nov 22 22:45:51 2020'

>>> time.asctime(time.localtime()) # 接受时间元组,转换成易读的字符串
'Sun Nov 22 22:47:51 2020

# 格式参考 https://www.runoob.com/python3/python3-date-time.html
>>> time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 接受一个时间元组,转换成%Y-%m-%d %H:%M:%S的格式
'2020-11-22 22:53:12'

#格式参考 https://www.runoob.com/python3/python3-date-time.html
>>> time.strptime("30 Nov 00", "%d %b %y") # 将30 Nov 00转换成时间元组
time.struct_time(tm_year=2000, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1)

>>> time.mktime(time.localtime()) # 将时间元组转换为时间戳
1606057052.0

datetime模块

datetime 比 time 高级了不少,可以理解为 datetime 基于 time 进行了封装,提供了更多实用的函数。在datetime 模块中包含了几个类,具体关系如下:

datetime 
    timedelta     # 主要用于计算时间跨度
    tzinfo        # 时区相关
    time          # 只关注时间
    date          # 只关注日期
    datetime      # 同时有时间和日期

名称比较绕口,在实际实用中,用得比较多的是 datetime.datetime 和 datetime.timedelta ,另外两个 datetime.date 和 datetime.time 实际使用和 datetime.datetime 并无太大差别。 下面主要讲讲 datetime.datetime 的使用。使用datetime.datetime.now()可以获得当前时刻的datetime.datetime 实例。 对于一个 datetime.datetime 实例,主要会有以下属性及常用方法,看名称就能理解,应该没有太大问题:

datetime.datetime类方法和属性

from datetime import datetime

类方法/属性名称    描述
datetime.today()    返回一个表示当前本期日期时间的datetime对象
datetime.now([tz])    返回指定时区日期时间的datetime对象,如果不指定tz参数则结果同上
datetime.utcnow()    返回当前utc日期时间的datetime对象
datetime.fromtimestamp(timestamp[, tz])    根据指定的时间戳创建一个datetime对象
datetime.utcfromtimestamp(timestamp)    根据指定的时间戳创建一个datetime对象
datetime.combine(date, time)    把指定的date和time对象整合成一个datetime对象
datetime.strptime(date_str, format)    将时间字符串转换为datetime对象

datetime.datetime类实例化对象的方法

from datetime import datetime
dt = datetime.now()

对象方法/属性名称    描述
dt.year, dt.month, dt.day    年、月、日
dt.hour, dt.minute, dt.second    时、分、秒
dt.microsecond, dt.tzinfo    微秒、时区信息
dt.date()    获取datetime对象对应的date对象
dt.time()    获取datetime对象对应的time对象, tzinfo 为None
dt.timetz()    获取datetime对象对应的time对象,tzinfo与datetime对象的tzinfo相同
dt.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]])    生成并返回一个新的datetime对象,如果所有参数都没有指定,则返回一个与原datetime对象相同的对象
dt.timetuple()    返回datetime对象对应的tuple(不包括tzinfo)
dt.utctimetuple()    返回datetime对象对应的utc时间的tuple(不包括tzinfo)
dt.toordinal()    同date对象
dt.weekday()    同date对象
dt.isocalendar()    同date独享
dt.isoformat([sep])    返回一个‘%Y-%m-%d
dt.ctime()    等价于time模块的time.ctime(time.mktime(d.timetuple()))
dt.strftime(format)    返回指定格式的时间字符串

示例

>>> from datetime import datetime
>>> timetime = datetime.now()

>>> timetime
datetime.datetime(2020, 11, 22, 23, 0, 5, 3814)

>>> timetime.year # 返回当前时间的年份
2020

>>> timetime.month # 返回当前时间的月份
11 

>>> timetime.day # 返回当前时间的日
22

>>> timetime.minute # 返回当前时间的分钟
0

>>> timetime.second # 返回当前时间的秒
5
>>> timetime.microsecond # 返回当前时间的微秒
3814

>>> timetime.date() # 返回date对象
datetime.date(2020, 11, 22)

>>> timetime.time() # 返回time对象
datetime.time(23, 0, 5, 3814)

>>> time.timetuple() # 将datetime对象转化为时间元组 
time.struct_time(tm_year=2020, tm_mon=11, tm_mday=22, tm_hour=23, tm_min=0, tm_sec=5, tm_wday=6, tm_yday=327, tm_isdst=-1)

>>> datetime.utcnow() # 返回当前UTC时间
datetime.datetime(2020, 11, 22, 15, 34, 58, 212017)

tzinfo对象是用来表示该时区相对UTC时间差值,和该地区是否执行夏时令的对象。datetime模块所提供的的tzinfo对象是一个抽象基类,也就是说我们不应该直接实例化此对象, 而应该以此类为基类,定义出子类,然后再实例化以供使用。在子类化的时候,需要自定义很多方法,非常繁琐。还好python提供了一个pytz的库,里面自带了适合各个国家和时区的tzinfo对象,我们可以直接使用。

在python中,我们把tzinfo为空的datetime对象称为是aware(觉醒)的,把tzinfo不为空的datetime对象称为naive(幼稚)的。使用datetime模块时,除非手动指定tzinfo属性,否则,创建出来的datatime对象tzinfo属性都默认为空。

aware 对象具有关于应用规则和时间调整的充分的信息,例如时区和夏令时信息,来定位相对其他aware 对象的位置。aware对象用于表示时间的一个特定的时刻,它是明确无二的。

naive 对象没有充分的信息来明确地相对其他日期/时间定位它自己。一个 naive 对象表示的是世界协调时(UTC)、本地时间还是其它时区的时间完全取决于程序,就像一个特定的数字表示的是米、英里还是质量一样。

注意,aware类型的datetime对象,只能和aware类型的datetime对象进行运算(相减,大小比较等)。navie类型的datetime对象,只能和naive类型的datetime对象进行运算(相减,大小比较等)。aware类型和naive类型之间运算会报错:

# datetime.replace(name=value) 前面所述各项属性是 read-only 的,需要此方法才可更改
>>> import pytz
>>> from datetime import datetime
>>> utc_tz = pytz.timezone('UTC')
>>> china_tz = pytz.timezone('Asia/Shanghai')

>>> zeze = datetime.now()
>>> zeze
datetime.datetime(2020, 11, 22, 18, 37, 45, 664648)

>>> zeze.strftime("%Y-%m-%d %H:%M:%S")
'2020-11-22 16:24:14'

>>> zeze2 = zeze.replace(tzinfo=china_tz) # 设置zeze中的tzinfo,需要使用replace
>>> zeze2
datetime.datetime(2020, 11, 22, 18, 37, 45, 664648, tzinfo=<DstTzInfo 'Asia/Shanghai' LMT+8:06:00 STD>)

>>> zeze3 = zeze.replace(tzinfo=utc_tz)
>>> zeze3
datetime.datetime(2020, 11, 22, 18, 37, 45, 664648, tzinfo=<UTC>)

# zeze2和zeze3的区别在于一个用UTC表示,一个用Asia/Shanghai表示
>>> zeze3-zeze2 # 表示两个时间的差值为29160秒,刚好是八个小时。
datetime.timedelta(seconds=29160)

常用轮子

在某个时间段内执行某个功能

import time
import datetime
DAY_start = datetime.time(8, 00)
DAY_end = datetime.time(12, 00)
NIGHT_start = datetime.time(13, 00)
NIGHT_end = datetime.time(18, 10)
if DAY_start <= datetime.datetime.now().time() <= DAY_end or NIGHT_start <= datetime.datetime.now().time() <= NIGHT_end:
    print("在上课之内")
else:
    print("不在上课之内")

比如周六执行某个任务

import datetime
today = datetime.datetime.now().weekday() + 1
print(today)
if today == 6:
    print("执行任务")

得到几月几号是星期几

import datetime
week = datetime.datetime.strptime("20200801", "%Y%m%d").weekday() + 1
print(week)

week = datetime.datetime.now().isoweekday()
print(week)

打印当前时间

import time
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

或者

import datetime
time = datetime.datetime.now()
print(time)

在某某时间点执行任务

下面的代码例子为在2021年6月8号16点45分执行任务。

import time, datetime
startTime = datetime.datetime(2021, 6, 8, 16, 45, 0)
print('Program not starting yet...')
while datetime.datetime.now() < startTime:
    time.sleep(1)
print('Program now starts on %s' % startTime)
print('Executing...')

参考自: Python小任务 - 如何编写指定时间执行的Python小程序