加减日期
可以采用两种方式来实现日期时间上的加减操作 ,一种是采用第三方库dateutil 这个是最简单的方式。另一种是使用python的基本库datetime和calendar结合使用,结合使用的原因是datetime的时间加减操作只能在周,天,时,分,秒,毫秒和微秒上进行时间的加减操作。下面时两种方式的实现方式 。
三方库dateutil
安装库
pip install python-dateutil
实现代码
导入dateutil.relativedelta中的relativedelta类,relativedelta
类定义了 __add__
和 __sub__
方法,这些方法接收 datetime
对象并根据 relativedelta
中的属性(如年、月、日等)进行相应的计算。当你执行 datetime_object + relativedelta_object
时,Python 实际上调用的是 relativedelta
的 __add__
方法,该方法会返回一个新的 datetime
对象。
from dateutil.relativedelta import relativedelta
from datetime import datetime
def add(
current_time=None,
adjust_type="add",
length=0,
unit="seconds"
):
# 时间增减逻辑
time_deltas = {
"second": relativedelta(seconds=length),
"minute": relativedelta(minutes=length),
"hour": relativedelta(hours=length),
"day": relativedelta(days=length),
"month": relativedelta(months=length),
"year": relativedelta(years=length),
}
# 调整时间
if adjust_type == "add":
new_time = current_time + time_deltas[unit]
else:
new_time = current_time - time_deltas[unit]
# 返回结果
return new_time
datetime和calendar结合
这两个都是python的基本库,不需要进行安装。
datetime只能进行周,天,时,分,秒,毫秒和微秒上的时间操作,所以我们主要是完成在实现对年月进行加减的逻辑处理问题。问题产生的原因是年的增减,影响 特定月2月天数28和29的变化,月的变化会影响到天和年,同样是 2月,当然也包含了其他月份30天和31天的一个变化。
- 首先年的变化,直接增加或者减少
- 月份的变化,需要进行一个转化,超出范围1-12后,我做的逻辑是区分大于12,还是小于1,通过循环,每满12个月就改变一次年和月,正确的将月份和年份对应的进行改变。
- 处理完年和月以后,要处理日期溢出问题,比如,从2024年2月29日减少12个月到2023年2月,2023年2月只有28天,此时如果只改变月份和年份,则会产生错误的日期数据,同时也会导致datetime时间对象报错。calendar.monthrange(new_year, new_month),拿到月份的日期范围,再获取到最大日期,进行取小操作,就能获取到正确的时间。
- 最后根据入参,使用datetime的timedelta进行剩下时间的操作。
from datetime import datetime
import calendar
def add_(current_time=None, years=0, months=0, days=0, hours=0, minutes=0, seconds=0):
# 加年份
new_year = current_time.year + years
# 加月份
new_month = current_time.month + months
while new_month > 12:
new_year += 1
new_month -= 12
while new_month < 1:
new_year -= 1
new_month += 12
# 处理日期溢出
last_day = calendar.monthrange(new_year, new_month)[1]
new_day = min(current_time.day, last_day)
# 创建新的日期
current_time = current_time.replace(year=new_year, month=new_month, day=new_day)
current_time += timedelta(days=days, hours=hours, minutes=minutes, seconds=seconds)
return current_time
同样我们可以简化这个代码,但是只能对一个时间类型进行操作,根据需要选择
from datetime import datetime
import calendar
def add__(current_time=None, unit="second", length=0):
unit_time = {
"year": 0,
"month": 0,
"day": 0,
"hour": 0,
"minute": 0,
"second": 0,
}
unit_time[unit] = length
# 加年份
new_year = current_time.year + unit_time["year"]
# 加月份
new_month = current_time.month + unit_time["month"]
# 年月调整
while new_month > 12:
new_year += 1
new_month -= 12
while new_month < 1:
new_year -= 1
new_month += 12
# 处理日期溢出
last_day = calendar.monthrange(new_year, new_month)[1]
new_day = min(current_time.day, last_day)
# 创建新的日期
current_time = current_time.replace(year=new_year, month=new_month, day=new_day)
current_time += timedelta(
days=unit_time["day"],
hours=unit_time["hour"],
minutes=unit_time["minute"],
seconds=unit_time["second"],
)
return current_time