python日期时间处理

1、time模块

time模块中时间的表现格式有三种:

  • timestamp:时间戳,表示的是从1970年1月1日00:00:00开始计算的秒数偏移量
  • struct_time: 时间元组,共包含9个元素
  • format_time: 格式化时间,已格式化的结构使时间更具可读性,包括自定义格式和固定时间

1.1 时间表现形式转换:

time.png

1.2 timestamp

time.time()
时间戳是从1970-01-0。1 00:00:00至今所经历的秒数,time.time()返回以秒为单位的浮点数时间戳,示例如下:

print(time.time())

执行结果如下:

1639815748.1144686

如果我们想获取10位的时间戳,可以通过int强制转换,直接去掉小数位,示例如下:

print(int(time.time()))

执行结果如下:

1639815748

如果想获取13位的时间戳,可以通过把秒数转换为毫秒的方法获得13位时间戳,示例如下:

print(int(round(time.time() * 1000)))

执行结果如下:

1639815748114

在Java中时间戳默认是以毫秒为单位,因此在Python测试运维代码中将时间戳转换为13位是比较常见的

1.3 struct_time

结构化时间元组,是包含9个元素的一个元组,其经常用于时间戳与格式化时间的转换媒介(结合格式化字符串的原理)
获取结构化时间元组有以下几个方法:

  • time.localtime(): 获取本地时间
  • time.gtime(): 获取格林威治时间
    示例如下:
# 可以不加时间戳参数,默认当前时间
lt = time.localtime()
print("当前本地时间为:", lt)  

# 获取格林威治天文时间(是指格林威治所在地的标准时间)
lt = time.gmtime()
print("格林威治时间为:", lt)

执行结果如下:

当前本地时间为: time.struct_time(tm_year=2021, tm_mon=12, tm_mday=18, tm_hour=18, tm_min=51, tm_sec=7, tm_wday=5, tm_yday=352, tm_isdst=0)
格林威治时间为: time.struct_time(tm_year=2021, tm_mon=12, tm_mday=18, tm_hour=10, tm_min=51, tm_sec=7, tm_wday=5, tm_yday=352, tm_isdst=0)

1.4 format_time

格式化后的时间日期会具有更好的可读性,其中固定格式常用方法如下:

  • time.ctime()
  • time.asctime()
    示例如下:
# 获取当前时间的格式化形式
lt = time.ctime(time.time())
print(lt)

# 获取当前时间的格式化形式
lt = time.asctime(time.localtime(time.time()))
print(lt)

执行结果如下:

Sat Dec 18 18:51:07 2021
Sat Dec 18 18:51:07 2021

执行结果中我们看到这两个函数的输出是完全相同的,那么这两者的区别是什么呢?其区别在于入参,ctime的入参是stamp,而asctime的入参是struct_time。在实际使用的过程中我们根据我们获取到的数据源来决定最终使用哪一个

1.5 stamptime、struct_time、format_time转换

在ctime函数中,是直接将stamptime转换为formattime格式的,但他的格式化是固定的,我们可以通过strftime方法来实现自定义的格式化时间,其接收的入参主要是struct_time,示例如下:

# 将时间格式化成 2021-12-17 12:20:30的形式
str_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(str_time)

# 将时间格式化成 Sat Mar 28 22:32:30 2021的形式
str_time = time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
print(str_time)

执行结果如下:

2021-12-18 18:51:07
Sat Dec 18 18:51:07 2021

同样,我们也可以把格式化字符串转换为时间戳,示例如下:

str_time = "2021-12-17 14:57:12"
stamp_time = time.mktime(time.strptime(str_time, "%Y-%m-%d %H:%M:%S"))
print(stamp_time)

执行结果如下:

1639724232.0

format_time常用的几个格式化表示:

注意:固定写法,不要创新!!
%Y---带世纪部分的十进制年份,例如2018
%m---十进制月份
%d---十进制表示的每月第几天(日)
%H---24小时制的小时
%M---十进制表示的分钟数
%S---十进制表示的秒数

从上面的示例中,我们可以看到struct_time通常是用来作为stamptime和format_time之间转换的一个中间媒介,可以思考下原因:
提示:
数据类型:浮点数,格式化日期时间
格式化字符串:多参数场景

2、datetime模块

datetime是Python中用于处理日期时间的一个模块,这个模块重新封装了time模块, 这个模块下有:date、time、datetime、timedelta、tzinfo等等多个类,大部分是不常用的,我们今天重点讲一下datetime这个类

2.1 date类

静态方法和字段

# date对象所能处理的最大、最小日期
print("date属性:date.max=", date.max)
print("date属性:date.min=", date.min)
# date对象表示日期的最小单位,这里是天
print("date属性:date.resolution=", date.resolution)
# 返回一个表示当前本地日期的date对象
print("当前本地时间:", date.today())
# 根据给定的时间戳,返回一个date对象
print(date.fromtimestamp(time.time()))

执行结果如下:

date属性:date.max= 9999-12-31
date属性:date.min= 0001-01-01
date属性:date.resolution= 1 day, 0:00:00
当前本地时间: 2021-12-19
2021-12-19

方法和属性

# date对象
d1 = date(2021, 11, 18)
# d1.year、date.month、date.day:年、月、日
print(d1.year, d1.month, d1.day)
# d1.replace(year, month, day):生成一个新的日期对象,用参数指定的年,月,日代替原有对象中的属性。(原有对象仍保持不变)
print(d1.replace(year=1988))
# d1.timetuple():返回日期对应的time.struct_time对象
print(d1.timetuple())
# 返回weekday,如果是星期一,返回0;如果是星期2,返回1,以此类推
print(d1.weekday())
# 返回weekday,如果是星期一,返回1;如果是星期2,返回2,以此类推
print(d1.isoweekday())
# 返回格式如(year,month,day)的元组
print(d1.isocalendar())
# 返回格式如'YYYY-MM-DD’的字符串
print(d1.isoformat())
# 格式化对象,和time模块format相同
print(d1.strftime("%Y_%m_%d"))

执行结果如下:

2021 11 18
1988-11-18
time.struct_time(tm_year=2021, tm_mon=11, tm_mday=18, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=322, tm_isdst=-1)
3
4
(2021, 46, 4)
2021-11-18
2021_11_18

Process finished with exit code 0

2.2 time类

静态方法和字段

from datetime import time as t
# time类所能表示的最小、最大时间
print(t.max)
print(t.min)
# 时间的最小单位,这里是1微秒(1秒=1000毫秒=1000000微秒)
print(t.resolution)

执行结果如下:

23:59:59.999999
00:00:00
0:00:00.000001

方法和属性

from datetime import time as t

# 创建time对象
tt = t(10, 23, 18)
# tt.hour、tt.minute、tt.second、tt.microsecond: 时、分、秒、微秒
print("hour: %d, minute: %d, second: %d, microsecond: %d" % (tt.hour, tt.minute, tt.second, tt.microsecond))

# tt.replace()创建一个新的时间对象,用参数指定时、分、秒、微秒代替原有对象中的属性(原有对象仍保持不变)
tr = tt.replace(hour=23, second=20)

# tt.isoformat():返回如"HH:MM:SS"格式的字符串表示
print(tt.isoformat())
print(tr.isoformat())

执行结果如下:

hour: 10, minute: 23, second: 18, microsecond: 0
10:23:18
23:23:20

2.3 datetime类

datetime类相当于date类和time类合起来,包含了日期、时间信息
静态方法和字段

# 返回一个表示当前本地时间的datetime对象
print(datetime.today())
# 返回一个表示当前本地时间的datetime对象,如果提供了参数tz,则获取tz参数所指时区的本地时间
# print(datetime.now([tz]))

# 返回一个当前UTC时间的datetime对象,即格林威治时间
print(datetime.utcnow())

# 根据时间戳创建一个datetime对象,参数tz指定时区信息
print(datetime.fromtimestamp(time.time()))
# print(datetime.fromtimestamp(time.time(), tz))

# 根据date和time,创建一个datetime对象
c_date = date(2021, 12, 21)
c_time = t(16, 16, 16)
print(c_date)
print(c_time)
print(datetime.combine(c_date, c_time))

# 将格式化字符串转换为datetime对象
# f_date = "2021-12-20" # 只传date没有time信息时,转换会报错:ValueError: time data '2021-12-20' does not match format '%Y-%m-%d %H:%M:%S'
f_datetime = "2021-12-20 12:12:12"
print(datetime.strptime(f_datetime, "%Y-%m-%d %H:%M:%S"))
print(type(datetime.strptime(f_datetime, "%Y-%m-%d %H:%M:%S")))

执行结果如下:

2021-12-20 14:18:27.929155
2021-12-20 06:18:27.929154
2021-12-20 14:18:27.929155
2021-12-21
16:16:16
2021-12-21 16:16:16
2021-12-20 12:12:12

方法和属性

# 创建datetime类对象
dt = datetime.now()
# 输出类属性
print(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, dt.microsecond, dt.tzinfo)

# 获取date对象
print(dt.date())
# 获取time对象
print(dt.time())
# 创建一个新的datetime对象,用参数指定年、月、日,时、分、秒、微秒代替原有对象中的属性(原有对象仍保持不变)
dr = dt.replace(year=2000)
# dr = dt.replace(year=2000, tzinfo=timezone.utc)
# 将datetime对象转换成时间戳
print(dr.timestamp())
# 这种方法必须指定tzinfo为utc时区,否则计算时会将当前时区(中国为UTC+8)和UTC的时间差换算后计算时间戳,导致得出的timestamp比UTC要快或者慢 n*3600秒(比如为中国时区则会慢8*3600s)  
print(type(dr.timestamp()))

执行结果如下:

2021 12 20 15 48 48 117061 None
2021-12-20
15:48:48.117061
977298528.117061

2.4 timedelta类

主要用作时间加减,使用timedelta可以很方便的在日期上做天、小时、分钟、秒、毫秒、微秒的时间计算,如果要计算月份则需要另外的办法

dd = datetime.now()
# 日期减一天
dd1 = dd + timedelta(days=-1) # 昨天
print(dd1)
dd2 = dd - timedelta(days=1)  # 昨天
print(dd2)
dd3 = dd + timedelta(days=1)  # 明天
print(dd3)

delta_ddt = dd3 - dd
print(delta_ddt, type(delta_ddt))

print(delta_ddt.days, delta_ddt.total_seconds()) 

执行结果如下:

2021-12-19 16:02:30.053801
2021-12-19 16:02:30.053801
2021-12-21 16:02:30.053801
1 day, 0:00:00 
1 86400.0

5、tzinfo类

tzinfo是关于时区信息的类,也是一个抽象类,不能被实例化

class UTC(tzinfo):
    """UTC"""
    def __init__(self, offset=0):
        self._offset = offset

    def utcoffset(self, dt):
        return timedelta(hours=self._offset)

    def tzname(self, dt):
        return "UTC +%s" % self._offset

    def dst(self, dt):
        return timedelta(hours=self._offset)


# 北京时间
beijing = datetime(2011, 11, 11, 0, 0, 0, tzinfo=UTC(8))
print("beijing time:", beijing)
# 曼谷时间
bangkok = datetime(2011, 11, 11, 0, 0, 0, tzinfo=UTC(7))
print("bangkok time", bangkok)
# 北京时间转成曼谷时间
print("beijing-time to bangkok-time:", beijing.astimezone(UTC(7)))

# 计算时间差时也会考虑时区的问题
timespan = beijing - bangkok
print("时差:", timespan)

执行结果如下:

beijing time: 2011-11-11 00:00:00+08:00
bangkok time 2011-11-11 00:00:00+07:00
beijing-time to bangkok-time: 2011-11-10 23:00:00+07:00
时差: -1 day, 23:00:00

你可能感兴趣的:(python日期时间处理)