最简单的日期计算公式~

文章介绍了如何避免繁琐的闰年和平年判断,使用蔡勒公式计算两个日期之间的天数差,以及如何通过公式确定任意日期是星期几。重点讲解了公式2、3和4的原理以及如何在C++代码中实现intsum_date函数。
摘要由CSDN通过智能技术生成

常规方法

  1. 计算0001-01-01到(xxxx-1)-12-31的公式是
    这里(xxxx-1)指的是去年,比如我们要算2024-02-29那么xxxx-1就代表2023年
                                
    TotalDay=365*y+\frac{y}{4}-\frac{y}{100}+\frac{y}{400}
    公式1

    其中,y:year,

    闰年分为普通闰年(能被4整除但不能被100整除)跟世纪闰年(能被400整除),365*year好理解,就是先算平年的所有天,

    y/4-y/100是计算0001-xxxx年间有多少个普通闰年,

    y/400是计算有多少个世纪闰年(多少个闰年就多多少天)

  2. 接着计算xxxx-01-01到xxxx-xx-xx的天数,执行1.+2.

  3. 如果计算两个日期差的话,就是两个天数相减

上面的计算是否麻烦的一些?还得判断xxxx是闰年还是平年,然后挨个月计算,那么是否有一种公式只需要年月日就可以计算出差多少天?——蔡勒公式

蔡勒公式

首先先给出蔡勒公式的表达式:

TotalDay=365*y+\frac{y}{4}-\frac{y}{100}+\frac{y}{400}+\frac{153*m-457}{5}-306+d
公式2


y:year, m:month, d:day

这是你要计算的日期

公式的前半部分好理解,就是计算0001-01-01到(xxxx-1)-12-31或者0001-01-01到xxxx-12-31的时间,区别这两种计算是因为我们计算月份的时候跨了年份,请看下面的例子。要想无需判断平年闰年就能计算出差多少天,首先一定得迈过2.28/2.29这个坎,其次闰年366天平年365天一定是在这两天变化的,其他月份不管是平年还是闰年都是一样的。于是该公式的起始时间是本年的3.01到明年的2.01此时完美避开了2.28/9,从而可以无需考虑该年是平年还是闰年。

让我们观察一下每个月的1号到3月1号的天数规律

月份该月天数该月1号到3月1号的天数差规律
33100
4303130+1
5316160+1
6309290+2
731122120+2
831153150+3
930184180+4
1031214210+4
1130245240+5
1231275270+5
1331306300+6
14未知337330+7

其中13表示明年的1月份,14表示明年的2月份

你会发现除了个位数,另一个是一个首项是0,公差是30的等差数列
现在的问题就变成找到一个函数拟合个位数的变化1,1,2,2,3,4,4,5,5,6,7
该函数就是
 

num(m)=\lfloor\frac{m*3-7}{5}\rfloor
公式3
m是月份,num值是其个位数

于是就有

(m-3)*30+\lfloor\frac{m*3-7}{5}\rfloor=\lfloor\frac{153m-457}{5}\rfloor
公式4
所以这个公式就是计算我们要求的month所在月的1号到3.01的天数

加上该月所在的天数day,就是总的TotalDay

那么306是哪来的呢, 看上面表格你会发现,306是指3.01-12.31这个时间的总和

那么为何要-306呢?我们来举两个例子

计算2024-02-27和计算2024-05-23(ps:下面说的公式前半部分指的是公式1,后半部分指的是公式4)

首先计算2024-02-27,由于是2月份(小于3月份)于是变成2023-14-27,带入公式得,由于公式的前半部分是计算了2023年一整年,所以这部分就是计算0001-01-01~2023-12-31的总天数,公式后半部分计算的是2023-03-01到2023-14-01(也就是2024-02-01)的总天数,这里也就有了重叠计算了两次2023-03-01到2023-12-31的天数,也就是306,于是公式就有减去306天了,最后在加上2月已过去27天,也就是2024-02-27已过去的天数了。

计算2024-05-23,由于是5月份(大于3月份)于是直接带入公式得,公式前半部分计算0001-01-01到2024-12-31的总天数,减去306天也就是变成0001-01-01到2024-03-01的总天数,公式后半部分计算的是3-01到5-01的总天数,两者相加就是2024-05-23已过去的天数了。

这里给出c++的代码

int sum_date(int y, int m, int d) {
    if (m < 3) {
        m += 12;
        y--;
    }
    return 365 * y + y / 4 - y / 100 + y / 400 + (153 * m - 457) / 5 + d - 306;
}

最后

算出了这个日期已过去多少天就可以秒杀很多题目了,包括但不限于,两个日期差多少天,给定一个日期算出今天是星期几?(totalday%7=0就是星期天,1就是星期一以此类推)

reference

【学习笔记】如何求出任意日期是星期几? - Superlova

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值