绪论
最近在做代码的时候,发现同一段计算基金产品MTD、QTD、YTD的代码中,同时出现了datatime和timestamp两种时间数据类型,于是决定做一定的梳理。梳理不全面,仅仅针对代码需要的部分,敬请补充完整。
严格来说,这两种数据类型分别为<class 'datetime.datetime'>
和<class 'pandas._libs.tslibs.timestamps.Timestamp'>
,分别属于datetime和pandas库。
定义和数据类型
按照今天是2023年10月3日为例,在命令行中,其定义、展示方法大致如下:
>>> today = '20231003'
>>> from datetime import *
>>> import pandas as pd
>>> today_d = datetime.strptime(today, '%Y%m%d')
>>> today_d
datetime.datetime(2023, 10, 3, 0, 0)
>>> today_t = pd.to_datetime(today)
>>> today_t
Timestamp('2023-10-03 00:00:00')
>>> type(today_d)
<class 'datetime.datetime'>
>>> type(today_t)
<class 'pandas._libs.tslibs.timestamps.Timestamp'>
两个和str转换的函数
首先是strftime方法。顾名思义,这是from time数据类型生成str。有意思的是,这两种数据类型都有这种方法。
>>> today_d.strftime('%Y%m%d')
'20231003'
>>> today_t.strftime('%Y%m%d')
'20231003'
另一种是strptime函数,例如上述datetime.strptime函数,就能够从str生成datatime类型的数据。但是暂时还没有发现timestamp中如何使用strptime函数。timestamp是靠pd.to_datetime函数初始化。
时间差分函数timedelta和relativedelta的区别
首先,timedelta函数的路径是datetime.timedelta,直接在datetime包中。而relativedelta函数的路径是dateutil.relativedelta.relativedelta,先需要导入:
>>> from dateutil.relativedelta import relativedelta
这两个函数都在于构造时间的差分,例如:
>>> (pd.to_datetime(today)-relativedelta(years=5)).strftime('%Y%m%d')
'20181003'
>>> (pd.to_datetime(today)+timedelta(days=-365)).strftime('%Y%m%d')
'20221003'
但是略有一些差异。我们先help一下,发现似乎relativedelta包含year, month, day, hour, minute, second, microsecond层面的时间差分,但是timedelta只能有timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)这么多的参数。这也就意味着,对于年层面的时间差分,只能用relativedelta。
此外,对于timestamp数据类型,既可以兼容使用datetime库中的timedelta函数,也可以使用relativedelta函数,得到Timestamp数据类型。甚至可以直接和datatime时间数据类型相加减,得到Timedelta数据类型:
>>> pd.to_datetime(today)-relativedelta(days=5)
Timestamp('2023-09-28 00:00:00')
>>> pd.to_datetime(today)-timedelta(days=-1)
Timestamp('2023-10-04 00:00:00')
>>> today_t-today_d
Timedelta('0 days 00:00:00')
而对于datetime数据类型,和上述一样,也能用这两个函数,只不过得到的结果是datetime数据类型。
>>> today_d+relativedelta(days=5)
datetime.datetime(2023, 10, 8, 0, 0)
>>> today_d-timedelta(days=-1)
datetime.datetime(2023, 10, 4, 0, 0)
由此可见,Python中的数据和函数的兼容性是比较强的。
时间差分函数的一些取巧应用
比如要求出上个月的最后一天。但是一般我们不知道上个月最后一天是28、29、30还是31,所以最好的逻辑是先求出本月第一天,再利用时间差分函数timedelta和relativedelta向前推一天:
>>> (datetime(datetime.strptime(today, '%Y%m%d').year,datetime.strptime(today, '%Y%m%d').month,1)+timedelta(days=-1)).strftime('%Y%m%d')
'20230930'
一些尚未确定的问题
timestamp中可否,以及如何使用strptime函数初始化。
datatime和timestamp两种时间数据类型的初始化和其他具体细节操作。
datatime和timestamp两种时间数据类型的更多差异,以及为什么要区分多种时间数据类型。
对于时间数据可以利用时间差分数据取巧使用,但是对于交易日数据,是否也可以类似的简单处理?我之前处理过例如“求出前五个交易日”的代码,但是需要用到Wind数据库中的trade_date数据再进行复杂处理,而不像这里有直接封装好的时间差分函数timedelta和relativedelta可以使用。在金融领域,这是一个非常有应用意义的问题。