关于计算两日期之间经过多少天的超巧妙算法

首先声明:本文引自一博主原创博客

昨天呢,刚刚阅读了这个代码,大部分都还可以看懂,有一两个地方属实难懂,但细细思来,方知博主此代码超神奇。简直巧妙至极。

所以来细细解析一下此代码。

话不多说。我们先来看一下原文。

include

这里呢是原文代码。

可以看到非常简短,接下来,就让你真正见识到这个代码的巧妙之处。

接下来我们先来看一下楼主的解析

算法解析:

该算法总体思想是计算给定日期到 0年3月1日的天数,然后相减,获取天数的间隔。

m1 = (month_start + 9) % 12; 用于判断日期是否大于3月(2月是判断闰年的标识),还用于纪录到3月的间隔月数。

y1 = year_start – m1/10; 如果是1月和2月,则不包括当前年(因为是计算到0年3月1日的天数)。

d1 = 365y1 + y1/4 – y1/100 + y1/400 + (m1306 + 5)/10 + (day_start – 1);

其中 365*y1 是不算闰年多出那一天的天数,

y1/4 – y1/100 + y1/400 是加所有闰年多出的那一天,

(m2*306 + 5)/10 用于计算到当前月到3月1日间的天数,306=365-31-28(1月和2月),5是全年中不是31天月份的个数

(day_start – 1) 用于计算当前日到1日的间隔天数
————————————————

我们由简到繁,慢慢分析:

其中关于最后的 (day_start – 1)就不用多说了吧。

我们主要来讲讲没别的地方。

先来看这里:

d1 = 365*y1 + y1/4 – y1/100 + y1/400

本文思路在这在说一下:即计算每个日期距离0年三月一日的相差天数,在做差即得两日期之间天数。

好了言归正传所谓闰年四年一闰,百年不闰,四百又多一闰。

我们从0年3月一日开始算到我们输入哪一年的3月一日截止先计算整年的天数总和。

0年的二月已过。所以考虑从1年到截止年的闰年个数。

用y1/4算出可被4整除的年数,我们记为疑是闰年年数。后我们减去y1/100,去掉其中的不是闰年年数,但是由于四百年又多一闰所以我们又加上了y1/400;

这样就可以完美的算出所经过的年的总天数,关于这里的年数还涉及后面的(- m1/10)一项,这个我们后面来细细解答,这里是本文最巧妙的地方之一,,先留个悬念哈。

好了我们接着往下看。

m1 = (month_start + 9) % 12;

这个就比较巧妙了,需要与

(m1*306 + 5)/10和(- m1/10)两项结合来分析。这里就到了作者算法最为精妙的部分了,不得不说这个代码真的神奇。

OK,继续。来看(- m1/10),和m1 = (month_start + 9) % 12;的结合。

先来看,怎么样才能让余数大于10呢,1,2,这两个结果对吧。如果是m1大于10 的话呢,可知年数会减一。

简单点来说呢就是用计算年总天数的计算到当年3月一号的天数总和,

如果当年不到三月,即1,2月,我们就往前推一年,计算到上一年的3月一号的天数,

至于多出来的天数我们接着看,别急。

县来看如果是1,n那么结果就是10,

即为一月份,意思是距离上一年的3月一号过去了10个月,对吧,

即上一年的3,4,5,6,7,8,9,10,11,12

其中一共有多少天呢,其中3.5.7.8.10.11位31天每月。

即结果为30*10+6

带入 (m1*306 + 5)/10即得真的为306;是不是很神奇。

我们将这个公式一一带入算一下。

下面呢 ,我们先看m1.再看月份,再看天数。

2,,,,,余11,4,5,6,7,8,9,10,11,12,1对吧,带入刚好为337;

3,,,,,余00

4,,,,,余13带入得31

5,,,,,余二3,4带入61;

6,,,,,余三3,4,5带入92

7,,,,,余四3,4,5,6带入122

8.,,,,,余五3,4,5,6,7带入153

9,,,,,余六,3,4,5,6,7,8带入184

10,,,,,余七,3,4,5,6,7,8,9滴入214

11,,,,,余8,3,4,5,6,7,8,9,10带入245

12,,,,,余9,,3,4,5,6,7,8,9,10,11带入275

OK,是不是发现都对,是不是很神奇。

我也这样觉得,我来为大家分析其玄妙之处

先来分析月份问题。

随余数的增加月份为3 4 5 6 7 8 9 10 11 12 1

先来看为31天的月份有,3 5 7 8 9 10 12 1

看一下其中大部分30,31天的月份间隔,对吧,

简单看一下即可看出由于306后面的6的原因及后面5的作用下

我们把它稍微化简一下化为(m1300+5+m16)/10

m1*300的我们直接滤掉

(5+6*m1)/10;

可以看到

1得1

2得1

3得2

最容易的得知的就是每加二回多一天即上面的初步规律30,31间隔出现

其中有两个特例,7到8,12到2

包含7,和7,8月份的余数分别为5,6

可以得出符合,

再看1到12你会发现一样符合,

到底为什么呢

多出来的6是最最中心的地方

月份每加一,在其原来的31,30紧挨着变化的情况下会多出来一个1

而当月份为5,10时,会凑乘5,而后再过一个月,按30,31来看为 偶数,是30天,不过由于6多出来的五和多一月多出来的6结合,又会造就一个31天,而且和前一个31天还是挨着的

所以,7月到8月的特例就包含了。

再看12月到1月的情况12月时余数为10,一月为11.

是不是又凑成一个5,后面一加有多出来一天。

OK,本次解析到此结束,

慢慢领悟此代码的玄妙之处吧

再见。嘿嘿

再次声明

代码不是我的

Original: https://www.cnblogs.com/cndccm/p/11974754.html
Author: Mr小明同学
Title: 关于计算两日期之间经过多少天的超巧妙算法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/573040/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • FaaS 基于多租户技术 SaaS平台设计

    多租户技术(英语:multi-tenancy technology)或称多重租赁 技术,是一种软件架构 技术,它是在探讨与实现如何于 多用户的环境下共用相同的系统或程序组件,并且仍…

    Java 2023年5月29日
    079
  • idea如何在创建类的同时加入作者的名字和时间等

    1、打开idea,左上角file-settings 2、在setting窗口找到editor目录下的”file and code template” 3、在…

    Java 2023年6月7日
    094
  • 数据结构与算法之希尔排序

    希尔排序则是通过添加一个步长的概念,每次把当前元素与增加步长后的元素比较,如果交换则交换.然后再次增加步长去比较,这个过程与插入排序一样.希尔排序与插入排序的 区别在于希尔排序通过…

    Java 2023年6月8日
    086
  • zk权限模块

    1 zk的权限控制 2 概述: 3 zk类&#x4F3…

    Java 2023年6月8日
    094
  • Effective Java 第三版——81. 优先使用并发实用程序替代wait和notify

    Tips书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code注意,书中的有些代码里方法是基于Java 9…

    Java 2023年5月29日
    079
  • 第三周

    第三周 1.测试成功的接口再次测试报错 原因:之前在查询时更改了方法,由Mybatis Plus 查询的方式改为了xml,同时在实体类中添加了字段做连表查询,导致之前所有用Myba…

    Java 2023年6月7日
    086
  • IDEA远程部署调试Java应用程序

    IDEA远程部署调试Java应用程序 IDEA远程部署调试Java应用程序 基本概述 准备工作 远程服务器准备 安装JDK 配置JAVA_HOME 项目准备 创建一个SpringB…

    Java 2023年6月5日
    094
  • VMware虚拟机系统无法使用桥接联网

    1、环境 VMware 14.1.1 虚拟系统:Windows Server 2008 32位 2、解决办法 打开虚拟网络编辑器 有红框中的提示出现时,就点击更改设置 点击桥接模式…

    Java 2023年6月5日
    082
  • 时间复杂度和空间复杂度

    写在前面 在学习数据结构和算法的时候,经常会碰到O(1),O(n)等等用来表示时间和空间复杂度,那这到底是什么意思。我们对于同一个问题经常有不同的解决方式,比如排序算法就有十种经典…

    Java 2023年6月5日
    060
  • 2020年度钻石C++C学习笔记(3)–《博学谷》

    1.Unix/Linux操作系统介绍 1.1 操作系统的作用 1.1.1 操作系统的目标 l 方便:使计算机系统易于使用 l 有效:以更有效的方式使用计算机系统资源 l 扩展:方便…

    Java 2023年6月7日
    079
  • nginx上传文件大小限制

    posted @2019-12-27 10:22 _小豪豪 阅读(1310 ) 评论() 编辑 Original: https://www.cnblogs.com/remember…

    Java 2023年5月30日
    083
  • JavaSE_多线程入门 线程安全 死锁 状态 通讯 线程池

    对JavaSE_多线程入门 线程安全 死锁 状态 通讯 线程池进行简要总结 1 多线程入门 1.1 多线程相关的概念 并发与并行 并行:在同一时刻,有多个任务在多个CPU上同时执行…

    Java 2023年6月9日
    075
  • SpringBoot设置项目欢迎页面与自定义Favicon图标

    前言 在上一章节中,威哥给大家讲解了在SpringBoot项目中如何处理静态资源,明白了静态资源的存储位置,今天我会对静态资源做进一步的处理。 既然我们的项目中存在多个页面,那在项…

    Java 2023年5月30日
    084
  • python的三层架构

    项目目录规范 Foo/ |– core/ # 存放业务逻辑相关代码 | |– core.py | |– api/ # 存放接口文件,接口主要用于为业务逻辑提供数据操作。 | …

    Java 2023年6月7日
    0100
  • spring boot websocket stomp 实现广播通信和一对一通信聊天

    一、前言 玩.net的时候,在asp.net下有一个叫 SignalR 的框架,可以在ASP .NET的Web项目中实现实时通信。刚接触java寻找相关替代品,发现 java 体系…

    Java 2023年5月30日
    061
  • 眼见不一定为实:调用链HBase倾斜修复

    hello,大家好,我是小楼。 今天给大家分享一个关于HBase数据倾斜的排查案例,不懂调用链?不懂HBase?没关系,看完包懂~ 背景 最近HBase负责人反馈HBase存储的调…

    Java 2023年6月6日
    076
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球