Python 不用第三方模块一行实现月份的加减

Python的datatime模块可以通过timedelta实行日期加减,但不能实现月份加减。如果要实现,可以使用第三方dateutil模块的relativedelta函数实现。但有时候系统不能安装第三方模块,可以简单用以下方式实现。

月份加减不能简单将月份+或-,因为各月日期数不同,如3月31号,月份减去1个月,不存在2月31日,因此,参考linux的date -d '+1 month'等运行结果,月份加减可以这样理解:

本日 + 1个月 = 下个月1日 + ( 本日 - 本月1日)
本日 - 1个月 = 上个月1日 + ( 本日 - 本月1日)

依次类推

本日  ± N个月 = ±N个月1日 + ( 本日 - 本月1日)

年份加减也一样(主要是为了处理闰年的2月29日,其余日期直接把年进行加减即可)

 本日 ± N年 = ±N年的同月1日 + ( 本日 - 本月1日)

实例如下:

import datetime
d1 = datetime.date(2020,3,28)
#上月同期:d2等于d1减去1个月(同时处理好1月的情况)
d2=d1.replace( year=d1.year+int((d1.month-13)/12), month=(d1.month+10)%12+1, day=1 ) + ( d1 - d1.replace(day=1) )
#用这个方法处理1月份也可以
#d2=d1.replace( year=d1.year-(1 if d1.month==1 else 0), month=(12 if d1.month==1 else d1.month-1), day=1 ) + ( d1 - d1.replace(day=1) )
#下月同期:d3等于d1加上1个月(同时处理好12月份)
d3=d1.replace( year=d1.year+int(d1.month/12), month=d1.month%12+1, day=1 ) + ( d1 - d1.replace(day=1) )
#上年同期:d4等于d1减去1年
d4 = d1.replace( year = d1.year - 1 , day = 1 ) + ( d1 - d1.replace( day = 1 ) )
print('选定日期',d1,'上月同期',d2,'下月同期',d3,'上年同期',d4)
运行结果:
选定日期: 2020-03-28 上月同期: 2020-02-28 下月同期: 2020-04-28 上年同期: 2019-03-28

如果将日期变为3月31日或闰年2月29日,运行结果分别如下

d1 = datetime.date(2023,3,31) 时的运行结果

选定日期: 2023-03-31 上月同期: 2023-03-03 下月同期: 2023-05-01 上年同期: 2022-03-31

d1 = datetime.date(2020,2,29) 时的运行结果

选定日期: 2020-02-29 上月同期: 2020-01-29 下月同期: 2020-03-29 上年同期: 2019-03-01

d1 = datetime.date(2020,12,31) 时的运行结果

选定日期: 2020-12-31 上月同期: 2020-12-01 下月同期: 2021-01-31 上年同期: 2019-12-31

d1 = datetime.date(2020,1,31) 时的运行结果

选定日期: 2020-01-31 上月同期: 2019-12-31 下月同期: 2020-03-02 上年同期: 2019-01-31

用这个方法得到的运行结果,跟linux系统的date -d 命令的+1 months或 -1 months或+1 years的结果是一样的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值