Zeller公式用于计算给定日期是星期几。

  该方法可以用数论知识进行证明。

  假设给定日期Date为Year-Month-Day,求解该日期是星期几的问题实际上就是以之前某个确定星期几的日期作为参考点,计算它们之间的总天数,然后再除以7取余数,即可算出指定日期是星期几。

  这里,我们将选择公元0年12月31日作为参考点。原则原因是:1、公元1年1月1日是周1;2、选择一年的末尾,便于以整年计算日期,防止过多分段计算带来的麻烦。

  由上可得,参考日期到给定日期的将分成两部分:PastYearsDays(过去的整数年天数)和PresentYearDays(指定年已流逝的天数);

  则可以得到,WholeDays = PastYearsDays + PresentYearDays。

  参考日期到指定日期经过的闰年数为:LeapYearsNum = [(Year - 1) / 4] - [(Year - 1) / 100] + [(Year - 1) / 400]。

  由上可得到,PastYearsDays =  (Year - 1) * 365 + LeapYearsNum。

  又因为(Year - 1) * 365 = (Year - 1) * ( 7 * 52 + 1) ≡ Year - 1 (mod 7),故可得到,PastYearsDays ≡Year - 1 + LeapYearsNum。

  因此,可得到WholeDays = PastYearsDays + PresentYearDays ≡ Year - 1 + LeapYearsNum + PresentYearDays  (mod 7)。

  接来下,我们开始计算PresentYearDays:

  下表分别展示了每个月的天数:

 
Month Jan. Feb. Mar. Fri. May. Jun. Jul. Aug. Sep Oct. Nov. Dec.
Days 31 28(29) 31 30 31 30 31 31 30 31 30 31

  又因为离28、29、30、31最近的7的倍数是28 = 4 * 7。故,当每个月的天数都减去28后可得如下表格:

 
Month Jan. Feb. Mar. Fri. May. Jun. Jul. Aug. Sep Oct. Nov. Dec.
LeftDays 3 0(1) 3 2 3 2 3 3 2 3 2 3
CommonYearAcc 3 3 6 8 11 13 16 19 21 24 26 29
LeapYearAcc 3 4 7 9 12 14 17 20 22 25 27 30

  除却1月和2月,3月-7月的剩余天数为:3,2,3,2,3;而8月-12月同样为:3,2,3,2,3。根据循环数列的规律(该理论将在另一博文中描述),可得到如下表述:

  当Month = 1时,PresentYearDays = Day;

  当Month = 2时,PresentYearDays = 31 + Day;

  当Month ≥ 3时,[13 * (Month  + 1) / 5] - 7 + (Month  - 1) * 28 + Day + i,其中,当闰年时i = 1,当平年时i = 0.

  

  将1月和2月当做上一年的“13月”和“14月”,最终上边三个公式将合并为以下公式:

  PresentYearDays  = [13 * (Month + 1) / 5] - 7 + (Month - 1) * 28 + Day         (3 ≤ Month ≤ 14)

  最终,WholeDays将变成:

  WholeDays ≡ (Year - 1) + [(Year - 1) / 4] - [(Year - 1) / 100] + [(Year - 1) / 400] + [13 * (Month +1) / 5 ] - 7 + (Month-1) * 28 + Day     (mod 7)

        ≡  (Year - 1) + [(Year - 1) / 4] - [(Year - 1) / 100] + [(Year - 1) / 400] + [13 * (Month +1) / 5 ] + Day                                     (mod 7)

  注意:当将1月和2月当做13月和14月计算的时候,年份也得减一。

  又因为每隔四个世纪,星期就重复一次。

  故我们可容易得到每个世纪的第一个月(3月1日)的计算公式:

  PastYearsDays‘ ≡ (4 - (Century - 1) mod 4) * 2 - 4            (mod 7)

  其中Century为给定时期所在的世纪。

  最终得到计算每隔世纪第一年的星期几的公式:

  WholeDays’ ≡  (4 - (Century - 1)  mod 4) * 2 - 1 + [13 * (Month + 1) / 5] + Day

  接下来,我们就要求在一个世纪内的任意天的星期。显然在一个世纪内,只需考虑能被4整除的年份即是闰年LeapYear,根据此规则,最终我们得到计算任意一天星期几的公式:

  WholeDays ≡ (4 - (Century - 1) mod 4) * 2 - 1 + (Year - 1) + [Year / 4] + [13 * (Month + 1) / 5] + Day

  假设C = Century - 1,根据数论知识,我们又可以得到如下公式:
  4q + r = C,其中q为商,r为余数。

  ⇒      r = C - 4 * [C / 4]

  ⇒      (4 - C mod 4) * 2 = (4 - C + 4 * [C / 4]) * 2 
                                            = 8 - 2C + 8 * [C / 4] 
                                            ≡ [C / 4] - 2C + 1         (mod 7)

  最终,由上式,我们可以得到

  WholeDay ≡ [C/4] - 2C + Year + [Year / 4] + [13 * (Month + 1) / 5] + Day - 1   (mod 7) 

  代码示例:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace TestOne
{
/// <summary>
/// Used to record Date.
/// </summary>
class LocalDate
{
public int m_nYear;
public int m_nMonth;
public int m_nDay; public LocalDate(int year, int month, int day)
{
m_nYear = year;
m_nMonth = month;
m_nDay = day;
} public LocalDate()
{
m_nYear = ;
m_nMonth = ;
m_nDay = ;
} /// <summary>
/// Used to calculate what day it is.
/// </summary>
/// <param name="localDate"></param>
/// <returns></returns>
public static int CalWhatDay(ref LocalDate localDate)
{
int year = localDate.m_nYear;
int month = localDate.m_nMonth;
int day = localDate.m_nDay;
if (month < )
{
year -= ;
month += ;
} int c = year / , y = year - * c;
int w = (c / ) - * c + y + (y / ) + ( * (month + ) / ) + day - ;
w = (w % + ) % ;
return w;
}
}
class Program
{
static void Main(string[] args)
{
LocalDate localDate = new LocalDate(, , );
int whatDay = LocalDate.CalWhatDay(ref localDate);
Console.WriteLine("Date: {0}-{1}-{2} is {3}", localDate.m_nYear, localDate.m_nMonth, localDate.m_nDay, PrintWahtDay(whatDay));
Console.ReadKey();
} private static string PrintWahtDay(int whatDay)
{
switch(whatDay)
{
case : return "Sunday";
case : return "Monday";
case : return "Tuesday";
case : return "Wednesday";
case : return "Thursday";
case : return "Friday";
case : return "Saturday";
default: return "Invalid number";
}
}
}
}

Code Here

Zeller公式推导及C#代码示例(待完善)的更多相关文章

  1. Mysql基础代码(不断完善中)

    Mysql基础代码,不断完善中~ /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限 ...

  2. 推荐Java五大微服务器及其代码示例教程

    来源素文宅博客:http://blog.yoodb.com/yoodb/article/detail/1339 微服务越来越多地用于开发领域,因为开发人员致力于创建更大,更复杂的应用程序,这些应用程序 ...

  3. 高级渲染技巧和代码示例 GPU Pro 7

    下载代码示例 移动设备正呈现着像素越来越高,屏幕尺寸越来越小的发展趋势. 由于像素着色的能耗非常大,因此 DPI 的增加以及移动设备固有的功耗受限环境为降低像素着色成本带来了巨大的压力. MSAA 有 ...

  4. Java8-Function使用及Groovy闭包的代码示例

    导航 定位 概述 代码示例 Java-Function Groovy闭包 定位 本文适用于想要了解Java8 Function接口编程及闭包表达式的筒鞋. 概述 在实际开发中,常常遇到使用模板模式的场 ...

  5. [IOS 开发] 懒加载 (延迟加载) 的基本方式,好处,代码示例

    懒加载的好处: 1> 不必将创建对象的代码全部写在viewDidLoad方法中,代码的可读性更强 2> 每个属性的getter方法中分别负责各自的实例化处理,代码彼此之间的独立性强,松耦合 ...

  6. SELECT控件操作的JS代码示例

    SELECT控件操作的JS代码示例 1 检测是否有选中 if(objSelect.selectedIndex > -1) { //说明选中 } else { //说明没有选中 } 2.动态创建s ...

  7. 转:HIBERNATE一些_方法_@注解_代码示例---写的非常好

    HIBERNATE一些_方法_@注解_代码示例操作数据库7步骤 : 1 创建一个SessionFactory对象 2 创建Session对象 3 开启事务Transaction : hibernate ...

  8. Python实现各种排序算法的代码示例总结

    Python实现各种排序算法的代码示例总结 作者:Donald Knuth 字体:[增加 减小] 类型:转载 时间:2015-12-11我要评论 这篇文章主要介绍了Python实现各种排序算法的代码示 ...

  9. C#与数据库访问技术总结(十五)之 DataAdapter对象代码示例

    DataAdapter对象代码示例 下面的代码将说明如何利用DataAdapter对象填充DataSet对象. private static string strConnect=" data ...

随机推荐

  1. Loadrunner 接口测试的两种方法

    其实无论用那种测试方法,接口测试的原理是通过测试程序模拟客户端向服务器发送请求报文,服务器接收请求报文后对相应的报文做出处理然后再把应答报文发送给客户端,客户端接收应答报文这一个过程. 方法一.用Lo ...

  2. readonly/disable input 问题

    Perhapes for surity, in chrome and IE10, readonly/disabled input will be reset when the form submit. ...

  3. Centos7 安装配置NFS

    一.安装 NFS 服务器所需的软件包 # yum install -y nfs-utils 二.编辑exports文件 # vim /etc/exports /data/disk1/video *(a ...

  4. PHP常用的数组相关处理函数

    [数组中常用的多种遍历方式] [for 和 foreach 略] [while() . list() .each() 组合循环遍历数组] each()函数 a. 需要一个数组作为参数 b. 返回来的也 ...

  5. ftp服务的搭建及调用

    首先是搭建 ftp server: 下载:http://archive.apache.org/dist/mina/ftpserver/1.0.6/ 下载到本地, 如下图:

  6. discuz阅读权限的设置作用

    为什么要有阅读权限?偶想很多新手有这个疑问吧,所以特开此帖说明下. 阅读权限的设置是帖子作者为了部分限制帖子的读者群.虽然网上发帖重在分享,但帖子(尤其精华帖子)是作者花时间和经历而写成的,不加阅读权 ...

  7. 【转】MySQL5安装的图解(mysql-5.0.27-win32.zip)

    转载地址:http://blog.csdn.net/xssh913913/article/details/1713182 MySQL5安装的图解(最新版) http://hi.baidu.com/yu ...

  8. SIM卡应用-OPN,PLMN,SPN

    SIM卡应用 移动运营商已经将SIM卡用於很多不同的应用,下面列出了其中最主要的应 用∶ ·漫游应用∶确保手机可以在漫游之後选择缺省的运营商网络.一个SIM应用是可以在手机漫游到某个合作夥伴运营商网络 ...

  9. Linux内核2.4.x的网络接口源码的结构[转]

    http://blog.csdn.net/wswifth/article/details/5102242 一.前言 Linux的源码里,网络接口的实现部份是非常值得一读的,通过读源码,不仅对网络协议会 ...

  10. Failed to start component [StandardEngine[Catalina].StandardHost[localhost....

    今天我用了近一天的时间研究一个错误,早上写代码是遇到一个 错误严重错误代码如下: 严重: ContainerBase.addChild: start: org.apache.catalina.Life ...