Python时间序列之datetime模块
在上篇Python时间序列的文章中Peter详细介绍了time模块,本文中重点介绍的是datetime模块。这个模块可以说是time模块的升级版本,使用的情况更为普遍和常见,用法也更为全面。文章中会通过各种例子来讲解模块的使用
Pandas文章
Pandas相关的文章更新到第26篇,近期的重点是:Python或Pandas中如何处理时间序列相关的数据。
上一篇文章是:time模块的讲解,请参考:
datetime模块
主要类
datetime模块中包含的主要类为:
- date:日期对象,常用的属性有year, month, day等
- time:时间对象,主要的属性有hour, minute, second, microsecond
- datetime:日期时间对象,属性date和属性datetime的组合
- datetime_CAPI:日期对象的C语言接口
- timedelta:两个时间之间的时间间隔
- tzinfo:时区信息对象的抽象基类
常量
主要是有两个常量:
- MAXYEAR:返回能表示的最大年份,datetime.MAXYEAR
- MINYEAR:返回能表示最小的年份,datetime.MINYEAR
5大类
下面介绍的datetime模块中5大类的具体使用方法:
- date
- time
- datetime
- timedelta
- tzinfo
在我们使用之前必须先把模块导进来
代码语言:javascript复制from datetime import * # *表示模块下面的所有类
date类
date对象由year年份、month月份及day日期三个部分来构成的:
当前时间
代码语言:javascript复制# 方式1
from datetime import date
datetime.today().date()
代码语言:javascript复制datetime.date(2021, 10, 20)
代码语言:javascript复制# 方式2
from datetime import date
# today是一个日期对象,返回的是当前日期
today = date.today()
today
代码语言:javascript复制datetime.date(2021, 10, 20)
通过year、month、day 3个属性描述符来访问:
代码语言:javascript复制print("今年:",today.year) # 返回today对象的年份
print("本月:",today.month) # 返回today对象的月份
print("今日:",today.day) # 返回today对象的日
代码语言:javascript复制今年: 2021
本月: 10
今日: 20
通过__getattribute__(…)方法获得上述值:
代码语言:javascript复制today.__getattribute__("year")
代码语言:javascript复制2021
代码语言:javascript复制today.__getattribute__("month")
代码语言:javascript复制10
代码语言:javascript复制today.__getattribute__("day")
代码语言:javascript复制20
此外,我们还可以访问其他的date类的信息:
代码语言:javascript复制print("当前日期:",today) # 当前日期
print("当前日期(字符串形式):",today.ctime()) # 返回日期的字符串
print("时间(元组形式):",today.timetuple()) # 当前日期的时间元组信息
代码语言:javascript复制当前日期: 2021-10-20
当前日期(字符串形式): Wed Oct 20 00:00:00 2021
时间(元组形式): time.struct_time(tm_year=2021, tm_mon=10, tm_mday=20, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=293, tm_isdst=-1)
代码语言:javascript复制print("本星期:",today.weekday()) # 0代表星期一,类推
print("公历序数:",today.toordinal()) # 返回公历日期的序数
print("年/周数/星期:",today.isocalendar()) # 返回一个元组:一年中的第几周,星期几
代码语言:javascript复制本星期: 2
公历序数: 738083
年/周数/星期: (2021, 42, 3)
自定义时间
指定一个任意的时间:
代码语言:javascript复制# 自定义一个时间
new_date = date(2021,12,8)
new_date
代码语言:javascript复制datetime.date(2021, 12, 8)
代码语言:javascript复制# 返回不同的属性
print("year: ", new_date.year)
print("month: ", new_date.month)
print("day: ", new_date.day)
代码语言:javascript复制year: 2021
month: 12
day: 8
代码语言:javascript复制# 返回时间元组
new_date.timetuple()
代码语言:javascript复制time.struct_time(tm_year=2021, tm_mon=12, tm_mday=8, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=2, tm_yday=342, tm_isdst=-1)
代码语言:javascript复制# 返回公历序数
new_date.toordinal()
代码语言:javascript复制738132
代码语言:javascript复制# 返回星期,0代表星期1,1代表星期2
new_date.weekday()
代码语言:javascript复制2
代码语言:javascript复制# 返回星期,1代表星期1,2代表星期2
new_date.isoweekday()
代码语言:javascript复制3
代码语言:javascript复制# 返回元组:(年份,第几周,周几)
new_date.isocalendar()
代码语言:javascript复制(2021, 49, 3)
代码语言:javascript复制# 以ISO 8601格式‘YYYY-MM-DD’返回date的字符串形式
new_date.isoformat()
代码语言:javascript复制'2021-12-08'
代码语言:javascript复制# 返回日期的字符串
new_date.ctime()
代码语言:javascript复制'Wed Dec 8 00:00:00 2021'
指定不同的日期输出格式:
代码语言:javascript复制# 返回指定格式的日期字符串
new_date.strftime("%Y-%m-%d")
代码语言:javascript复制'2021-12-08'
代码语言:javascript复制new_date.strftime("%Y/%m/%d")
代码语言:javascript复制'2021/12/08'
代码语言:javascript复制new_date.strftime("%Y年%m月%d日")
代码语言:javascript复制'2021年12月08日'
代码语言:javascript复制# 替换时间,比如我们替换new_date
r_date = new_date.replace(2021,11,10)
r_date
代码语言:javascript复制datetime.date(2021, 11, 10)
在这种情况下,我们就生成了一个新的date对象,当然我们还可以显示的指定参数:
代码语言:javascript复制new_date.replace(year=2021,month=11,day=11)
代码语言:javascript复制datetime.date(2021, 11, 11)
公历序数相关
公历序数是和toordinal方法相关的
代码语言:javascript复制# 查看当前日期的公历序数
to_timestamp = today.toordinal()
to_timestamp
代码语言:javascript复制738083
将给定的公历序数转成具体的时间日期:fromordinal
代码语言:javascript复制print(date.fromordinal(to_timestamp))
代码语言:javascript复制2021-10-20
时间戳转化
通过函数fromtimestamp进行转化
代码语言:javascript复制import time
t = time.time() # 当前时间的时间戳
t
代码语言:javascript复制1634732660.382036
代码语言:javascript复制print(date.fromtimestamp(t)) # 时间戳--->日期
代码语言:javascript复制2021-10-20
转化任意的时间戳:
代码语言:javascript复制date.fromtimestamp(1698382719)
代码语言:javascript复制datetime.date(2023, 10, 27)
时间格式化
代码语言:javascript复制# 下面我们对today对象进行格式化输出
today
代码语言:javascript复制datetime.date(2021, 10, 20)
代码语言:javascript复制print(today.strftime("%Y/%m/%d"))
代码语言:javascript复制2021/10/20
代码语言:javascript复制print(today.strftime("%Y-%m-%d"))
代码语言:javascript复制2021-10-20
time类
创建对象
先创建一个任意的时间
代码语言:javascript复制from datetime import time
t = time(20,30,40,1000)
访问常见属性
时分秒都是常见的属性
代码语言:javascript复制print(t.hour) # 时
print(t.minute) # 分
print(t.second) # 秒
print(t.microsecond) # 微秒
代码语言:javascript复制20
30
40
1000
格式化输出
代码语言:javascript复制# 返回 ISO 8601格式的时间字符串
t.isoformat()
代码语言:javascript复制'20:30:40.001000'
代码语言:javascript复制# 指定输出的格式
t.strftime("%H:%M:%S:%f")
代码语言:javascript复制'20:30:40:001000'
同样的,也具有替换功能:
代码语言:javascript复制# 隐式替换
t.replace(14,37,8)
代码语言:javascript复制datetime.time(14, 37, 8, 1000)
代码语言:javascript复制# 显式替换
t.replace(hour=4,minute=18,second=19)
代码语言:javascript复制datetime.time(4, 18, 19, 1000)
datetime类
datetime对象包含date对象和time对象的所有信息。专属于datetime的方法和属性汇总:
- date(…):返回datetime对象的日期部分
- time(…):返回datetime对象的时间部分
- utctimetuple(…):返回UTC时间元组部分
生成当前日期
代码语言:javascript复制from datetime import datetime
k = datetime.today() # 当前具体时间
print(k)
代码语言:javascript复制2021-10-20 20:24:23.053493
访问当前时间的不同属性信息:
代码语言:javascript复制print("year:",k.year)
print("month:",k.month)
print("day:",k.day)
代码语言:javascript复制year: 2021
month: 10
day: 20
生成当前时间
代码语言:javascript复制# 返回当前的具体时间
n = datetime.now()
n
代码语言:javascript复制datetime.datetime(2021, 10, 20, 20, 24, 23, 694127)
代码语言:javascript复制# 返回datetime对象的日期部分
n.date()
代码语言:javascript复制datetime.date(2021, 10, 20)
代码语言:javascript复制# 返回datetime对象的时间部分
n.time()
代码语言:javascript复制datetime.time(20, 24, 23, 694127)
代码语言:javascript复制# 返回datetime对象的UTC时间元组部分
n.utctimetuple()
代码语言:javascript复制time.struct_time(tm_year=2021, tm_mon=10, tm_mday=20, tm_hour=20, tm_min=24, tm_sec=23, tm_wday=2, tm_yday=293, tm_isdst=0)
还可以生成其他的属性信息:
代码语言:javascript复制# 返回当前UTC日期和时间的datetime对象
print(datetime.utcnow())
代码语言:javascript复制2021-10-20 12:24:24.241577
代码语言:javascript复制# 给定时间戳的datetime对象
print(datetime.fromtimestamp(1697302830))
代码语言:javascript复制2023-10-15 01:00:30
代码语言:javascript复制# 指定公历序数的datetime对象
print(datetime.fromordinal(738000) )
代码语言:javascript复制2021-07-29 00:00:00
代码语言:javascript复制# 拼接日期和时间
print(datetime.combine(date(2020,12,25), time(11,22,54)))
代码语言:javascript复制2020-12-25 11:22:54
指定任意时间
代码语言:javascript复制# 指定一个任意时间
d = datetime(2021,9,25,11,24,23)
代码语言:javascript复制print(d.date()) # 日期
print(d.time()) # 时间
print(d.timetz()) # 从datetime中拆分出具体时区属性的time
print(d.timetuple()) # 时间元组
print(d.toordinal()) # 和date.toordinal一样
print(d.weekday()) # 两种星期
print(d.isoweekday())
print(d.isocalendar()) # ISO格式化输出
print(d.isoformat())
print(d.strftime("%Y-%m-%d %H:%M:%S")) # 指定格式
print(d.replace(year=2021,month=1)) # 替换
代码语言:javascript复制2021-09-25
11:24:23
11:24:23
time.struct_time(tm_year=2021, tm_mon=9, tm_mday=25, tm_hour=11, tm_min=24, tm_sec=23, tm_wday=5, tm_yday=268, tm_isdst=-1)
738058
5
6
(2021, 38, 6)
2021-09-25T11:24:23
2021-09-25 11:24:23
2021-01-25 11:24:23
格式化输出
代码语言:javascript复制# 直接对时间的格式化输出
print(datetime.strptime("2020-12-25","%Y-%m-%d"))
代码语言:javascript复制2020-12-25 00:00:00
对给定的datetime对象的格式化输出,比如上面创建的实例化对象k:
代码语言:javascript复制k
代码语言:javascript复制datetime.datetime(2021, 10, 20, 20, 24, 23, 53493)
代码语言:javascript复制# 格式化输出
k.strftime("%Y-%m-%d %H:%M:%S")
代码语言:javascript复制'2021-10-20 20:24:23'
timedelta类
timedelta对象表示一个时间段,即两个日期 (date) 或日期时间 (datetime) 之间的差值。
目前支持参数:weeks、days、hours、minutes、seconds、milliseconds、microseconds。
当前日期
代码语言:javascript复制from datetime import timedelta, date, datetime
d = date.today() # 当前日期
d
代码语言:javascript复制datetime.date(2021, 10, 20)
代码语言:javascript复制print("今天:",d)
print("加上5天:",d timedelta(days=5)) # 加上5天
print("加上3天 8小时:", d timedelta(days=3,hours=8)) # 加上3天和8个小时
代码语言:javascript复制今天: 2021-10-20
加上5天: 2021-10-25
加上3天 8小时: 2021-10-23
当前时间点
代码语言:javascript复制# 当前时间点
now = datetime.now()
now
代码语言:javascript复制datetime.datetime(2021, 10, 20, 20, 24, 26, 777335)
代码语言:javascript复制print(now timedelta(hours=4)) # 加上4个小时
print(now timedelta(weeks=2)) # 加上2个礼拜
print(now - timedelta(seconds=500)) # 减去500秒
代码语言:javascript复制2021-10-21 00:24:26.777335
2021-11-03 20:24:26.777335
2021-10-20 20:16:06.777335
datetime对象差值
代码语言:javascript复制delta = datetime(2020,12,26) - datetime(2020,12,12,20,12)
print(delta)
代码语言:javascript复制13 days, 3:48:00
代码语言:javascript复制delta.days # 日期间隔:天
代码语言:javascript复制13
代码语言:javascript复制delta.seconds # 日期间隔:秒
代码语言:javascript复制13680
代码语言:javascript复制delta.total_seconds() # # 全部转成秒
代码语言:javascript复制1136880.0
两个日期差值
代码语言:javascript复制d1 = datetime(2021,10,1)
d2 = datetime(2021,10,8)
代码语言:javascript复制d1.__sub__(d2) # d1 - d2
代码语言:javascript复制datetime.timedelta(days=-7)
代码语言:javascript复制d2.__sub__(d1) # d2 - d1
代码语言:javascript复制datetime.timedelta(days=7)
代码语言:javascript复制# rsub表示用d2 - d1
d1.__rsub__(d2)
代码语言:javascript复制datetime.timedelta(days=7)
上面两个日期的差值结果是datetime.timedelta, 如果获得整数类型的结果则按下面的方法操作:
代码语言:javascript复制d1.__sub__(d2).days
代码语言:javascript复制-7
tzinfo类
主要作用是指定时间所在的时区
指定时区
代码语言:javascript复制from datetime import date, timedelta, datetime, timezone
tz_utc_8 = timezone(timedelta(hours=8)) # 创建时区
print(tz_utc_8)
代码语言:javascript复制UTC 08:00
代码语言:javascript复制now = datetime.now()
print(now)
代码语言:javascript复制2021-10-20 20:24:28.844732
代码语言:javascript复制new_time = now.replace(tzinfo=tz_utc_8) # 强制加上8个小时
print(new_time)
代码语言:javascript复制2021-10-20 20:24:28.844732 08:00
时区切换
代码语言:javascript复制# 获取UTC时间
utc_now = datetime.utcnow().replace(tzinfo=timezone.utc) # 指定utc时区
print(utc_now)
代码语言:javascript复制2021-10-20 12:24:29.336367 00:00
代码语言:javascript复制# 通过astimezone切换到东八区
beijing = utc_now.astimezone(timezone(timedelta(hours=8)))
print(beijing)
代码语言:javascript复制2021-10-20 20:24:29.336367 08:00
代码语言:javascript复制# UTC时区切换到东九区:东京时间
tokyo = utc_now.astimezone(timezone(timedelta(hours=9)))
print(tokyo)
代码语言:javascript复制2021-10-20 21:24:29.336367 09:00
代码语言:javascript复制# 北京时间(东八区)直接切换到东京时间(东九区)
tokyo_new = beijing.astimezone(timezone(timedelta(hours=9)))
print(tokyo_new)
代码语言:javascript复制2021-10-20 21:24:29.336367 09:00
常见应用
时间戳转成日期
代码语言:javascript复制import time
now_timestamp = time.time()
now_timestamp
代码语言:javascript复制1634732670.286224
代码语言:javascript复制# 1-转成具体时间点
now = time.ctime(now_timestamp)
print(now)
代码语言:javascript复制Wed Oct 20 20:24:30 2021
代码语言:javascript复制# 2-时间戳先转成时间元组,strftime在转成指定格式
now_tuple = time.localtime(now_timestamp)
print(now_tuple)
代码语言:javascript复制time.struct_time(tm_year=2021, tm_mon=10, tm_mday=20, tm_hour=20, tm_min=24, tm_sec=30, tm_wday=2, tm_yday=293, tm_isdst=0)
代码语言:javascript复制time.strftime("%Y/%m/%d %H:%M:%S", now_tuple)
代码语言:javascript复制'2021/10/20 20:24:30'
代码语言:javascript复制# 选择一个具体的时间戳
timestamp = 1618852721
a = time.localtime(timestamp) # 获得时间元组形式数据
print("时间元组数据:",a)
time.strftime("%Y/%m/%d %H:%M:%S", a) # 格式化
代码语言:javascript复制时间元组数据: time.struct_time(tm_year=2021, tm_mon=4, tm_mday=20, tm_hour=1, tm_min=18, tm_sec=41, tm_wday=1, tm_yday=110, tm_isdst=0)
'2021/04/20 01:18:41'
代码语言:javascript复制time.ctime(1618852741)
代码语言:javascript复制'Tue Apr 20 01:19:01 2021'
日期时间转成时间戳
给定一个字符串类型的日期数据,如何转化成我们想要的时间格式呢?
代码语言:javascript复制date = "2021-10-26 11:45:34"
# 1、时间字符串转成时间数组形式
date_array = time.strptime(date, "%Y-%m-%d %H:%M:%S")
date_array
代码语言:javascript复制time.struct_time(tm_year=2021, tm_mon=10, tm_mday=26, tm_hour=11, tm_min=45, tm_sec=34, tm_wday=1, tm_yday=299, tm_isdst=-1)
代码语言:javascript复制# 2、查看时间数组数据
print("时间数组:", date_array)
代码语言:javascript复制时间数组: time.struct_time(tm_year=2021, tm_mon=10, tm_mday=26, tm_hour=11, tm_min=45, tm_sec=34, tm_wday=1, tm_yday=299, tm_isdst=-1)
代码语言:javascript复制# 3、mktime时间数组转成时间戳
time.mktime(date_array)
代码语言:javascript复制1635219934.0
日期格式化
代码语言:javascript复制import time
old = "2021-09-12 12:28:45"
# 1、转换成时间数组
time_array = time.strptime(old, "%Y-%m-%d %H:%M:%S")
# 2、转换成新的时间格式(2021/09/12 12-28-45)
new = time.strftime("%Y/%m/%d %H-%M-%S",time_array) # 指定显示格式
print("原格式时间:",old)
print("新格式时间:",new)
代码语言:javascript复制原格式时间: 2021-09-12 12:28:45
新格式时间: 2021/09/12 12-28-45