总天数以及星期几的计算算法

在写程序的过程中,需要判断两个日期是否处在一个星期之内,如果用C++类库CTime,则只能计算1970年之后的日期,之前的日期就会报错,于是研究了几个星期计算算法,改写出一个计算从1年1月1日起到输入日期之间的天数,如果他们的除数相同,则表明他们在一个星期之内(原理参见参考文章《蔡勒算法》),同时该方法也可以计算两个日期之间的天数差。

日期计算关于《1582年10月4日和1752年9月3日 》这两个日期都有特殊的历史,蔡勒公式和基姆拉尔森公式也都给出了在特殊日期前后的计算方式,如计算的日期在这两个日期之前,需要特殊计算。

  1 // CDate.cpp : 定义控制台应用程序的入口点。
  2
  3 #include "stdafx.h"
  4 #include "atltime.h"
  5 #include<iostream>
  6 #include<string>
  7 using namespace std;
  8
  9 int GetTotalDays(int y,int m, int d);
 10 int ZellerWeekDay(int y,int m, int d);
 11 int CaculateWeekDay(int y,int m,int d);
 12 int GetWeekDay(int y,int m,int d);
 13 string GetWeekStr(int w);
 14 bool is_valid(int m,int d,int y);
 15
 16 int _tmain(int argc, _TCHAR* argv[])
 17 {
 18     int month,day,year;
 19     while(true)
 20     {
 21         cout<<"输入一个日期:yyyy mm dd: ";
 22         cin>>year>>month>>day;
 23         if(is_valid(month,day,year))
 24         {
 25             int nTotalDays = GetTotalDays(year,month,day);
 26             string strWeek = GetWeekStr((nTotalDays - 1) % 7);
 27             cout<<"总天数:"<<nTotalDays<<"    星期"<<strWeek<<endl;
 28
 29             int nWeek = ZellerWeekDay(year,month,day);
 30             strWeek = GetWeekStr(nWeek);
 31             cout<<"Zeller公式计算结果:星期"<<strWeek<<endl;
 32
 33             nWeek = CaculateWeekDay(year,month,day);
 34             strWeek = GetWeekStr(nWeek);
 35             cout<<"基姆拉尔森公式计算结果:星期"<<strWeek<<endl;
 36
 37             nWeek = GetWeekDay(year,month,day);
 38             strWeek = GetWeekStr(nWeek);
 39             cout<<"类库函数计算结果:星期"<<strWeek<<endl;
 40             cout<<endl;
 41         }
 42         else
 43         cout<<year<<"-"<<month<<"-"<<day<<"是一个错误的日期."<<endl;
 44     }
 45 }
 46
 47 //改写算法计算总天数,可以计算日期处在第几周
 48 int GetTotalDays(int y,int m, int d)
 49 {
 50     //下面是根据蔡勒(Zeller)公式改写的算法
 51     int  leap= 0;
 52     if(m==1){m=13;y--;}
 53     if(m==2){m=14;y--;}
 54     if (y > 0 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
 55             leap++;
 56     y--;
 57     //计算从1.1.1日起至当前日期的天数
 58     int nTotalDays = 365*y + y/4 - y/100 + y/400 + 13*(m+1)/5 - 7 + 28*(m-1)+d + leap;
 59     return  nTotalDays;
 60 }
 61
 62 //蔡勒公式
 63 int ZellerWeekDay(int y,int m, int d)
 64 {
 65     int week = 0;
 66     if(m==1){m=13;y--;}
 67     if(m==2){m=14;y--;}
 68     int c = y / 100;
 69     y = y % 100;
 70     week = y + y/4 + c/4 - 2*c + (13*(m+1))/5 + d - 1;
 71     week = (week -1) % 7;
 72     return week;
 73 }
 74
 75 //基姆拉尔森公式计算星期几
 76 int CaculateWeekDay(int y,int m, int d)
 77 {
 78     int week;
 79     if(m==1){m=13;y--;}
 80     if(m==2){m=14;y--;}
 81     //if((y<1752)||((y==1752)&&(m<9))||((y==1752)&&(m==9)&&(d<3))) //判断是否在1752年9月3日之前
 82     //    week =(d+2*m+3*(m+1)/5+y+y/4+5)%7; //1752年9月3日之前的公式
 83     //else
 84         week =(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7; //1752年9月3日之后的公式
 85     return week;
 86 }
 87
 88 //获取星期几用于验算
 89 int GetWeekDay(int y,int m,int d)
 90 {
 91     int week = -1;
 92     if (y > 1900)
 93     {
 94         CTime tm(y,m,d,0,0,0);
 95         week = tm.GetDayOfWeek();
 96         week = (week + 5) % 7;
 97     }
 98     return week;
 99 }
100
101 string GetWeekStr(int w)
102 {
103     string weekstr;
104     switch(w)
105     {
106     case 0: {weekstr="一"; break;}
107     case 1: {weekstr="二"; break;}
108     case 2: {weekstr="三"; break;}
109     case 3: {weekstr="四"; break;}
110     case 4: {weekstr="五"; break;}
111     case 5: {weekstr="六"; break;}
112     case 6: {weekstr="日"; break;}
113     }
114     return weekstr;
115 }
116
117 bool is_valid(int m,int d,int y)
118 {
119 if(m<0||m>12||d<0||d>31||y<0)
120 return false;
121 return true;
122 }
时间: 2024-08-29 12:11:07

总天数以及星期几的计算算法的相关文章

输入一个日期,判断这个日期在一年中是哪一天,是星期几,计算两个日期间的天数,使用字符串输出日期

之前写了一个博文(http://blog.csdn.net/shiwazone/article/details/45053739)是用基本函数实现的,这次使用类的设计方法,也就是面向对象的方法改写一下,并加入了日期转换成字符串的实现.这里的程序也可以解决编程珠玑习题3.4的问题. #include"calendar.h" int main() { Time t; t.initialTime(); t.Show(); t.StrShow(); Time t1; t1.initialTim

转- 关于时间,日期,星期,月份的算法(Java中Calendar的使用方法)

package cn.outofmemory.codes.Date; import java.util.Calendar; import java.util.Date; public class CalendarDemo { public static void main(String[] args) { Calendar calendar=Calendar.getInstance(); calendar.setTime(new Date()); System.out.println("现在时间

关于时间,日期,星期,月份的算法(Java中Calendar的使用方法)(一)

package cn.outofmemory.codes.Date; import java.util.Calendar; import java.util.Date; public class CalendarDemo { public static void main(String[] args) { Calendar calendar=Calendar.getInstance(); calendar.setTime(new Date()); System.out.println("现在时间

关于时间,日期,星期,月份的算法(Java中Calendar的用法)(一)

package cn.outofmemory.codes.Date; import java.util.Calendar; import java.util.Date; public class CalendarDemo { public static void main(String[] args) { Calendar calendar=Calendar.getInstance(); calendar.setTime(new Date()); System.out.println("如今时间

用户输入商品生产日期和保质期(天数),通过程序计算促销日期。

* 用户输入商品生产日期和保质期(天数),通过程序计算促销日期. * 计算规则为:到保质期前14天所在周的周三为促销日. /** * 用户输入商品生产日期和保质期(天数),通过程序计算促销日期. * 计算规则为:到保质期前14天所在周的周三为促销日.控制台交互情况如图-1所示 * 思路: * 1. 用户输入生产日期和保质期(天数),就可以求出 过期日期 * 2. 通过过期日期减去14天即为促销日期所在的周 * 3. 通过所在周求出周三的日期 * 算法: * 1.通过用户输入的两个日期,转换生产日

集合相似度对比的两种计算算法

相似度对比的两种计算算法:Jaccard similarity相似性系数和Ochiai coefficient落和系数 Jaccard coefficient:A,B分别代表符合某种条件的集合:两个集合交集的大小/两个集合并集的大小,交集=并集意味着2个集合完全重合. Ochiai coefficient:A,B分别代表符合某种条件的集合:两个集合的交集大小/两个集合大小的几何平均值.是余弦相似性的一种形式. 相关参考链接:http://en.wikipedia.org/wiki/Jaccard

java实现两个日期内具有几个星期几的计算

虽然java自带的Calendar类似乎很好用,但是作为小白的我还不会用.朋友说有时需要计算任意两个日期内具有几个星期一或者星期三.问我能不能实现,我想想,能实现,可能代码不够优雅.具体代码放在下面.欢迎朋友与我分享更好的思路或工具吧~ package cn.example.mapper; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import ja

星期几的计算 (if语句)

public boolean chackyear(int str) {// 判断平年,闰年 boolean q = str % 4 == 0; boolean w = str % 100 == 0; boolean e = str % 400 == 0; boolean r = false; if (q) { if (w == false || e) { r = true; } } return r; } public String chackday(int year, int month, i

计算算法时间复杂度的主方法的一种较为简洁的记忆方法

这阵子在认真地看着算法导论,之前看到第四章计算分治法的时间复杂度的计算方法被称为“主方法”,运用这个主方法可以快速地口算出分治算法的递归式的时间复杂度,以下给出算法导论里关于主方法的描述吧,我就直接截图 不得不说,算法导论是一本非常偏向于数学的算法书,里面的对于各种算法结论的正确性大都有着严格的数学上的推导.之前对于主方法的描述只是大略地看了一下,看是看懂了,但是当时没有刻意将这个结论记下来,当我往后看遇到递归式求解部分的时候发觉还是忘记了主方法的求解过程,只能模糊记得部分而已,昨天晚上再复习的