Python基础学习之时间模块 time模块 & datetime模块详解

Python基础学习之时间模块 time模块 datetime模块

Python中,关于时间的模块,常用为:time & datetime 两个模块;
时间相关的模块虽然内容挺多,但是并不需要死记硬背,只要留个印象就好;因为实际编程中,对时间的使用相对固定,主要为以下场景:

  1. 计算程序的运行时间;
  2. 时间类型转换;系统生成的log中的时间字符串,变化成需要的格式化字符串格式;
  3. 时间的运算;
  4. 固定时间运行程序;
    以上的场景,在实例中给出,参考 5.0 实例;我觉得只要 5.0 的三个例子可以掌握,就基本够用了;

1. time 模块

1.1 time 模块_时间转换的关系图

在这里插入图片描述

备注:可视化时间其实就是格式化字符串;

1.2 时间转换方法详解

1.2.1 引入time 模块

# 引入time 模块
import time

1.2.2 获取时间戳

# 当前时间戳
time.time()    # 输出:1600853751.2822378

1.2.3 当前时间元组

# 当前时间元组
time.localtime()
# 输出: time.struct_time(tm_year=2020, tm_mon=9, tm_mday=23, tm_hour=17, tm_min=37, tm_sec=22, tm_wday=2, tm_yday=267, tm_isdst=0)
# 实际上时间元组是:(2020,9,23,17,37,22,2,267,0)
#     时间元组(年、月、日、时、分、秒、一周的第几日、一年的第几日、夏令时)
#         一周的第几日: 0-6
#         一年的第几日: 1-366
#         夏令时: -1, 0, 1

1.2.4 时间戳 ==> 时间元组;localtime() & gmtime()

# 时间戳 ==> 时间元组
time.localtime(1600853751.2822378)    # 传入时间戳,输出对应的时间元组;
# time.struct_time(tm_year=2020, tm_mon=9, tm_mday=23, tm_hour=17, tm_min=35, tm_sec=51, tm_wday=2, tm_yday=267, tm_isdst=0)
time.gmtime(1600853751.2822378)     # 返回的时间为格林威治时间,即比我们的时间早 8 小时 
# time.struct_time(tm_year=2020, tm_mon=9, tm_mday=23, tm_hour=9, tm_min=35, tm_sec=51, tm_wday=2, tm_yday=267, tm_isdst=0)

1.2.5 时间戳 ==> 可视化时间;ctime()

# 时间戳 ==> 可视化时间
time.ctime()   # 输出:Wed Sep 23 17:41:32 2020
time.ctime(1600853751.2822378)    # 传入时间戳,输出:Wed Sep 23 17:35:51 2020

1.2.6 时间元组 ==> 时间戳;mktime()

# 时间元组 ==> 时间戳
time.mktime(time.localtime())    # 输出:1600853842.0
time.mktime((2020,9,23,17,37,22,2,267,0))   # 输出:1600855090.0

1.2.7 时间元组 ==> 可视化时间(默认格式);asctime()

# 时间元组 ==> 可视化时间
time.asctime()   # 输出:Wed Sep 23 17:50:56 2020
time.asctime(time.localtime())   # 输出:Wed Sep 23 17:52:55 2020
time.asctime((2020,9,23,17,37,22,2,267,0))   # 输出:Wed Sep 23 17:37:22 2020

1.2.8 时间元组 ==> 可视化时间(自定义格式);strftime()

# 时间元组 ==> 可视化时间(定制)
time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())  # 输出:2020-09-23 18:09:00
time.strftime("%Y-%m-%d %H:%M:%S", (2020,9,23,17,37,22,2,267,0))    # 输出:2020-09-23 17:37:22

自定义格式时的代表字符,这里的内容,在时间模块中通用,想要自定义时间的输出格式,就需要用到以下内容:

'''
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
'''

1.2.9 可视化时间(定制) ==> 时间元组

#  可视化时间(定制) ==> 时间元组   time.strptime(时间字符串,时间格式)
time.strptime('2020-09-23 17:37:22', '%Y-%m-%d %H:%M:%S')   # 输出:time.struct_time(tm_year=2020, tm_mon=9, tm_mday=23, tm_hour=17, tm_min=37, tm_sec=22, tm_wday=2, tm_yday=267, tm_isdst=-1)

1.3 时区 (time.tzname) & 延时函数 (time.sleep)

1.3.1 time.tzname 返回当地的时区名称和夏令时;

[bytes([ord(c) for c in s]).decode('gbk') for s in time.tzname]
# 输出:['中国标准时间', '中国夏令时']

1.3.2 time.sleep(secs) 推迟调用线程的运行,secs指秒数

a = time.time()
time.sleep(5)
b=time.time()
print(b-a)    # 5.000340700149536  五秒延时

2. datetime 模块

2.1 datetime 模块_时间转换的关系图

在这里插入图片描述

备注:

  1. 可视化时间其实就是格式化字符串;
  2. 详细的每个方法如何使用,参考下文;

2.2 datetime 对象类的方法

2.2.1 模块的导入;

# 方法一:    # 本文章所用的是第一个方法;
import datetime
# 方法二:
from datetime import datetime

2.2.2 当前日期 & 时间;now() & today()

# 返回本地时间的datetime 对象
datetime.datetime.now()   # 输出:2020-09-23 19:48:42.222601
datetime.datetime.today()   # 输出:2020-09-23 19:48:42.222602

2.2.3 格林威治日期 & 时间;utcnow()

# 返回格林威治时间 的 datetime 对象
datetime.datetime.utcnow()    # 输出:2020-09-23 11:51:33.029317   比北京时间早8小时

2.2.4 时间戳 ==> datetime 对象 ;fromtimestamp(时间戳)

# 将时间戳 ==> datetime 对象,其中:时间戳通过time模块获得 time.time()
datetime.datetime.fromtimestamp(1600853751)     # 输出:2020-09-23 17:35:51

2.2.5 时间戳 ==> datetime 对象(格林威治时间);utcfromtimestamp(时间戳)

# 将时间戳 ==> datetime 对象(格林威治时间)
datetime.datetime.utcfromtimestamp(1600853751)     # 输出:2020-09-23 09:35:51  比北京时间早8小时

2.2.6 返回一个datetime, 距离公元 0 年间隔指定天数; fromordinal(天数)

# 返回距离公元0年的时间,datetime.fromordinal(天数)
datetime.datetime.fromordinal(20)    # 输出:0001-01-20 00:00:00 表示距离0-0-0 20天的时间

2.2.7 日期 & 时间 拼接 combine(date,time)

# 拼接date 和 time 对象,返回一个datetime对象
date = datetime.datetime.today().date()
time = datetime.datetime.today().time()
newdatetime= datetime.datetime.combine(date,time)
print(newdatetime)    # 输出:2020-09-23 20:09:57.651732

2.2.8 字符串 ==> datetime对象; strptime(字符串)

# 将格式化字符串转化成datetime对象;看着输出没有变化,其实类型变成了datetime,可以使用对应的属性;
datetime.datetime.strptime('2020-09-23 20:09:57','%Y-%m-%d %H:%M:%S')   # 输出:2020-09-23 20:09:57
datetime.datetime.strptime('2020-09-23', '%Y-%m-%d')    # 输出:2020-09-23 00:00:00
datetime.datetime.strptime('2020-09-23', '%Y-%m-%d').year    # 输出: 2020

2.2.9 datetime对象 ==> 字符串; str()

a=datetime.datetime.strptime('2020-09-23', '%Y-%m-%d')
print(a)     # 输出:2020-09-23 00:00:00
print(type(a))    # 输出:<class 'datetime.datetime'>
b = str(a)
print(b)    # 输出:2020-09-23 00:00:00
print(type(b))    # 输出:<class 'str'>

2.3 datatime 对象实例的方法

2.3.1 创建datetime 实例

# 创建datetime实例,常用的方法;
datetime.datetime(2020, 9, 23, 15, 50, 6)    # 输出:2020-09-23 15:50:06
datetime.datetime.today()   # 输出:2020-09-23 19:48:42.222601

2.3.2 date() 方法 & time() 方法

# date() 方法
datetime.datetime.today().date()    # 输出:2020-09-23

# time() 方法
datetime.datetime.today().time()    # 输出:20:27:42.009573

2.3.3 datetime ==> 时间戳;timestamp()

# timestamp() 方法 , 返回对应datetime的时间戳
datetime.datetime.today().timestamp()     # 输出:1600864222.266731

2.3.4 datetime ==> 可视化时间(格式化字符串);ctime()

# ctime() ,返回默认的字符串格式
datetime.datetime.today().ctime()    # 输出:Wed Sep 23 20:37:26 2020

2.3.5 datetime ==> 可视化时间(自定义的格式化字符串);strftime()

# strftime(), 返回格式化字符串,格式可以自己定义;
datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S')   # 输出:2020-09-23 20:39:07

2.3.6 星期几? weekday() 方法 & isoweekday()

# weekday() 方法,返回星期, 星期一为 0,星期天为 6
datetime.datetime.today().weekday()      # 输出:2 说明是星期三
# isoweekday(), 返回星期, 星期一为 1,星期天为 7
datetime.datetime.today().isoweekday()      # 输出:3 说明是星期三

2.3.7 返回一个元组,包含:年,周,星期;isocalendar()

# isocalendar(),返回一个元组,包含:年,周,星期
datetime.datetime.today().isocalendar()    # 输出:(2020, 39, 3)

2.3.8 返回公元0年到指定时间的天数;toordinal()

# toordinal(), 返回公元0年到指定时间的天数
datetime.datetime.today().toordinal()    # 输出:737691

2.4 datatime 对象实例的属性

常用属性就是:年,月,日,时,分,秒,可以直接使用属性得到对应的值,举例如下:

# datetime 对象的属性
datetime.datetime.today().year    # 输出:2020
datetime.datetime.today().month    # 输出:9
datetime.datetime.today().day    # 输出:23
datetime.datetime.today().hour    # 输出:20
datetime.datetime.today().minute    # 输出:45
datetime.datetime.today().second    # 输出:10
datetime.datetime.today().microsecond    # 输出:782152

import pytz                           
sh = pytz.timezone('Asia/Shanghai')    # 不指定,输出None
datetime.datetime(2020,9,23,tzinfo=sh).tzinfo    # 用处不大,输出:Asia/Shanghai

3. datetime 模块与 time 模块的区别

  1. time 的时间范围:1970年 - 2038年,1970.1.1 00:00:00以秒计算的偏移量
    datatime 的时间范围:0年 - 9999年
  2. datetime 是 time 的高级封装,所以比time模块的功能强大一些;
  3. 在对时间要求不多的项目里,两个模块都可以满足需求;

4. 时间的运算

时间的运算常常使用两个方法:timedelta() & relativedelta()

4.1 timedelta()

该方法属于 datetime 模块,可以计算周,天,时,分,秒的运算,不能计算年和月。举例如下:

# 周,天,时,分,秒的运算,可以使用timedelta();这里的参数都可以是浮点型;
a = datetime.timedelta(weeks=1)   # 给 a 赋值,一周的时间
# days, seconds, microseconds, milliseconds, minutes, hours, weeks 以上的这些参数都可以,然后datetime类型的时间就可以加减了;
b = a + datetime.datetime.today()    # 当前时间 + 时间间隔(一周),赋值给 b;
print(b)      # 输出:2020-10-01 12:56:41.216884    输出一周后的时间,如果嫌弃秒后有小数,可以去掉;
b.strftime('%Y-%m-%d %H:%M:%S')   # 输出:2020-10-01 12:56:41, 这样就去掉了小数;

4.2 relativedelta()

该方法属于dateutil模块,所以需要先引入模块,才可以使用;引入方式如下:

from dateutil.relativedelta import relativedelta

引入后,可以通过该模块计算年,月,日,时,分,秒,周,工作日等;举例如下:

# 年,月,天,周,时,分,秒,工作日,闰年等都可以使用 relativedelta,
from dateutil.relativedelta import relativedelta
a = relativedelta(b)
'''
参数定义如下:
dt1=None, dt2=None,
years=0, months=0, days=0, leapdays=0, weeks=0,
hours=0, minutes=0, seconds=0, microseconds=0,
year=None, month=None, day=None, weekday=None,
yearday=None, nlyearday=None,
hour=None, minute=None, second=None, microsecond=None
''' 
# 上面的参数都可以是浮点型;
a = datetime.datetime.today()   # 当前时间:2020-10-01 12:54:38.821073
c = datetime.datetime.today() + relativedelta(days=0.5)
print(c)    # 输出一天后的时间:2020-09-25 12:54:38.828092   因为此时的c是datetime 类型,所以可以使用strftime()随意的制定输出格式;
c.strftime('%Y-%m-%d %H:%M:%S')  # 输出:2020-09-25 12:54:38

d= datetime.datetime.today() + relativedelta(years=1)
print(d)    # 输出一年后的时间:2021-09-24 12:55:59.793014
d.strftime('%Y-%m-%d %H:%M:%S')  # 输出:2021-09-24 12:55:59

5. 实例

一般的项目中,可能并不需要我们对时间模块有过多的了解,所以需要时再回来看每个用法就可以了,下面举几个常用的例子,可以满足平时的大部分使用环境;

5.1 程序运行时间

# 1. 程序运行时间;
import time
a = time.time()    # 记录开始时间

# 以下是函数体
i = 0
while i<1000000:
    i+=1
    pass

b = time.time()    # 记录结束时间
print(b-a)    # 输出:0.08823347091674805

5.2 时间类型的转换

应用场景:工业中设备生产 log 中一般包含时间信息,这些时间信息为字符串格式,当格式不满足使用习惯时,我们需要变更时间格式;例如:Wed Sep 23 17:52:55 2020 ==> 2020-9-23 17:52:55,实现代码如下:

# Wed Sep 23 17:52:55 2020  ==> 2020-9-23 17:52:55
import datetime

a = 'Wed Sep 23 17:52:55 2020'    # 原始的时间格式

b = datetime.datetime.strptime(a, '%a %b %d %H:%M:%S %Y')   # 现在 b 就是 datetime 对象; %a %b %d %H:%M:%S %Y 与 Wed Sep 23 17:52:55 2020 一一对应;代表字符参考:1.2.8 自定义格式时的代表字符;
print(b)    # 输出:2020-09-23 17:52:55

# 当时间是datetime对象时,我们就可以使用 strftime(),随意去定制输出的格式了;举例如下:
b.strftime('%Y-%m-%d %H:%M:%S')    # 输出:2020-09-23 17:52:55 (字符串格式)
b.strftime('%Y-%m-%d %H:%M')    # 不要秒的格式:2020-09-23 17:52
b.strftime('%y-%m-%d %H:%M')  # 简化的年:20-09-23 17:52

5.3 时间的运算;timedelta() & relativedelta()

计算今天(2020-09-24)的18天后是哪天;代码如下:

from dateutil.relativedelta import relativedelta
a = datetime.datetime.today()    # 输出:2020-09-24 13:19:25.642956
b = relativedelta(days=18)
c = a + b     # 此时c为:2020-10-12 13:19:25.642956
print(c)    # 此时c为:2020-10-12 13:19:25.642956
print( a.strftime('%Y-%m-%d') + '的18天后是'+c.strftime('%Y-%m-%d'))   # 格式化输出结果:2020-09-24的10天后是2020-10-12

5.4 固定时间运行程序

每隔10分钟,运行一次程序;

import time,os

def sleep_time(hour,min,sec):
    return hour * 3600 + min * 30 +sec

sleep = sleep_time(0,10,0)
while True:
    time.sleep(sleep)
    print('开始执行;')
    print('现在时间为:' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(a)))
    os.system(r'D:\print_fun.py')
    print('执行完成;')

每天早上 7:00 运行程序;

import time, os

while True:
    time_now = time.strftime("%H:%M", time.localtime())
    if time_now == '07:00':
        print('开始执行;')
        print('现在时间为:' + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        os.system(r'D:\print_fun.py')
        print('执行完成;')
        time.sleep(60)  # 因为我们是以分钟作为匹配值的,所以程序运行后,延时60s,确保程序不重复执行;

5.5 打印进度条

def progress(percent,width=50):
    if percent > 1:
        percent=1
    show_str=('[%%-%ds]' %width) %(int(width*percent) * '#')
    print('\r%s %d%%' %(show_str,int(100*percent)),end='')


import time
recv_size=0
total_size=100000
while recv_size < total_size:
    time.sleep(0.1)
    recv_size+=100
    percent=recv_size / total_size
    progress(percent)

输出:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_47139649/article/details/108757610