一个日期算法的原理分析

1、问题描述

在 OSC 问答频道有一个问题:时间算法:帮忙解答下

简单的复述一遍就是能够通过如下式子来计算month月day日是一年的第几天。

闰年是 day_of_year=(275*month)/9 - (month+9)/12 + day - 30

非闰年比这个少1天。可以简单的验证,这个式子中每个部分计算后都取整,整个结果总是对的。

我们知道1、3、5、7、8、10、12都是31天,2月的天数有点诡异,其他都是30天,正常情况下我们写程序会写很多if来判断月份,进而计算累积的天数。但是为什么这个式子不用if就搞定了呢?式子中很奇怪的275、9、12,都是这么来的呢?

2、原理分析

简单的分析下,式子可以变形为:

day_of_year=【(275*month)/9 - 30】 - 【(month+9)/12】 + 【day】

=【30*(month-1)】+ 【5*month/9】+【day】-【(month+9)/12】

这样可以把式子分成4个部分,我们一一来解释这四个部分的含义:

part1:30*(month-1)

part2:5*month/9

part3:day

part4:(month+9)/12

1)我们知道,计算x月y日的天数,实际上真正需要计算的就是前面(x-1)个月的天数之和,加上y,即可。

这里的y就是part3中的day。

2)然后我们只需要计算前面的(x-1)个月的天数之和了。

我们可以先假设每个月都只有30天,然后计算正三五七八十腊多出来的1天(下面第四条)和二月不足30的天数(下面第二条),合起来就是准确的天数了。假设每个月都是30天,那么一共就是30*(x-1)
天,这就是part1。

3)对闰年来说,2月29天,比30天少1天,但是呢,只有x大于等于3的时候,天数里才包含这个29,所以找一个大于等于3的时候等于1的式子就可以了。比如当前的例子中用的是part4,即(month+9)/12。同理,用(month+8)/11、或(month+7)/10其实也一样。(month+6)/9就不行了,因为month=12时,它等于2了。

4)最后我们再来分析正三五七八十腊这些大月多出来的1天。

我们可以先统计一下每个月之前所有的大月累积多出来的一天之和sum。例如5月份的话,前面有1、2、3、4四个月,只有1、3月是大月比30天多1天,所以sum=2.对应的表格如下:

x
  =>  sum

1
  => 0

2
  => 1

3
  => 1

4
  => 2

5
  => 2

6
  => 3

7
  => 3

8
  => 4

9
  => 5 (规则开始变化、发生了“跃迁”)

10
 => 5

11
 => 6

12  =>
6

如果有个函数能表示这个sum(x),就可以直接用来计算多出来的天数了。

这个函数有个特点,在x小于9的时候,值为x/2取整; 在x大于等于9、小于等于12的时候,值为(x+1)/2取整。

恰好part2,即5*x/9 取整可以满足这一点(不信可以自己计算下)。类似的式子可以找出来很多,但是可以证明分母最小的就是5/9;也可以证明如果“跃迁”发生在sum(8)=5或者sum(7)=4,那么对应的函数可以是5/8*month, 4/7*month。

我们也可以注意到,函数值近似于1/2,而5/9也差不多就是1/2。

一个整数x乘以1/2,其小数部分要么为0(x为偶数的时候),要么为1/2(x为奇数的时候)。

而5/9比1/2大1/18,所以x小于9的时候,5/9*x的值与x/2的值之差,一直小于9/18=1/2,他们取整是相等的(小数部分小于1/2+1/2=1)。

而在x大于等于9的时候,差值>=9/18=1/2了,所以,x为偶数的时候,函数值为x/2,为奇数的时候,变成x/2+1。

这两个合并到一起就是(x+1)/2取整。所以part2即可以用来表示sum(x). 把part1、part2、part3、part4合起来就是准确的天数了。

类似的,式子part2可以用5/9到5/8之间的任何分数代替,例如51/90*month,50/89*month...等等。

当然这里讨论的都是不用if判断,直接表达出来的方式,如果可以用一个if判断,最简单的是:

如果小于8,直接除以2取整;否则,加1除以2取整。

一个日期算法的原理分析,布布扣,bubuko.com

时间: 2024-10-13 02:12:30

一个日期算法的原理分析的相关文章

非对称加密技术- RSA算法数学原理分析

非对称加密技术,在现在网络中,有非常广泛应用.加密技术更是数字货币的基础. 所谓非对称,就是指该算法需要一对密钥,使用其中一个(公钥)加密,则需要用另一个(私钥)才能解密.但是对于其原理大部分同学应该都是一知半解,今天就来分析下经典的非对称加密算法 - RSA算法.通过本文的分析,可以更好的理解非对称加密原理,可以让我们更好的使用非对称加密技术. 题外话: 本博客一直有打算写一系列文章通俗的密码学,昨天给站点上https, 因其中使用了RSA算法,就查了一下,发现现在网上介绍RSA算法的文章都写

foreach的一个“奇怪”现象——实现原理分析

先看一个长长的代码,其实很简单,就是使用不同的方法迭代Map,对值进行修改,只要遇到foreach就发现赋值看似成功,实则失败. 就想搞清楚为什么,不想直接从搜索引擎搜来别人的总结好的背下来. 1.问题的引出 1.1.测试的源代码    1: public static void main(String[] args) {    2:     Map<String, String[]> map = new HashMap<String, String[]>();    3:    

Adaboost算法原理分析和实例+代码(简明易懂)

Adaboost算法原理分析和实例+代码(简明易懂) [尊重原创,转载请注明出处] http://blog.csdn.net/guyuealian/article/details/70995333     本人最初了解AdaBoost算法着实是花了几天时间,才明白他的基本原理.也许是自己能力有限吧,很多资料也是看得懵懵懂懂.网上找了一下关于Adaboost算法原理分析,大都是你复制我,我摘抄你,反正我也搞不清谁是原创.有些资料给出的Adaboost实例,要么是没有代码,要么省略很多步骤,让初学者

手动实现一个单词统计MapReduce程序与过程原理分析

[toc] 手动实现一个单词统计MapReduce程序与过程原理分析 前言 我们知道,在搭建好hadoop环境后,可以运行wordcount程序来体验一下hadoop的功能,该程序在hadoop目录下的share/hadoop/mapreduce目录中,通过下面的命令: yarn jar $HADOOP_HOME/share/hadoop/mapreducehadoop-mapreduce-examples-2.6.4.jar wordcount inputPath outPath 即可对输入文

常见hash算法的原理(转)

常见hash算法的原理 散列表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法.顾名思义,该数据结构可以理解为一个线性表,但是其中的元素不是紧密排列的,而是可能存在空隙. 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的数组叫做散列表. 比如我们存储70个元素,但我们可能为这70个元素申请了100个元素的空间.7

深入理解HTTP协议、HTTP协议原理分析

深入理解HTTP协议.HTTP协议原理分析 目录(?)[+] http协议学习系列 1. 基础概念篇 1.1 介绍 HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写.它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本.其中最著名的就是RFC 26

常见hash算法的原理

转自:http://blog.csdn.net/zxycode007/article/details/6999984 散列表,它是基于快速存取的角度设计的,也是一种典型的“空间换时间”的做法.顾名思义,该数据结构可以理解为一个线性表,但是其中的元素不是紧密排列的,而是可能存在空隙. 散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度.这个映射函数叫做散列函数,存放记录的

Servlet过滤器介绍之原理分析

zhangjunhd 的BLOG   写留言去学院学习发消息 加友情链接进家园 加好友 博客统计信息 51CTO博客之星 用户名:zhangjunhd文章数:110 评论数:858访问量:1923464无忧币:6720博客积分:6145博客等级:8注册日期:2007-02-03 热门专题更多>> Linux系统基础之菜鸟进阶 阅读量:2359 ARM驱动之Linux驱动程序设计入门 阅读量:2252 HTML5入门教程 阅读量:1392 深入浅出学MySQL 阅读量:1558 热门文章 基于T

12种排序算法:原理、图解、动画视频演示、代码以及笔试面试题目中的应用

出处:http://blog.csdn.net/han_xiaoyang/article/details/12163251. 声明:版权所有,转载请注明出处,谢谢. 0.前言 从这一部分开始直接切入我们计算机互联网笔试面试中的重头戏算法了,初始的想法是找一条主线,比如数据结构或者解题思路方法,将博主见过做过整理过的算法题逐个分析一遍(博主当年自己学算法就是用这种比较笨的刷题学的,囧),不过又想了想,算法这东西,博主自己学的过程中一直深感,基础还是非常重要的,很多难题是基础类数据结构和题目的思想综