回 帖 发 新 帖 刷新版面

主题:求星期几

程序有些长,不过很容易看懂,就是根据一些计算法则,给出一个年月日,输出是星期几,对于这个程序,在非闰年的情况下输出都是正确的,但是一到闰年,计算1,2月份的时候,就出错,应该是我标出的地方出错了,不过我找半天也没看出来。。。。。
#include <iostream>
using namespace std;
bool isleapyear(int year)
{ bool leap_year=((year%400==0)||(year%4==0&&year%100!=0));
return leap_year;
}
int getcenturyvalue(int year)
{ year=year/100;
year=year%4;
year=3-year;
year=year*2;
return year;
}
int getyearvalue(int year)
{int year1,year2;
year1=year%100;
year2=year1/4;
year=year1+year2;
return year;
}
int getmonthvalue(int month,int year)
{int m;
switch(month)
{ [color=800000]case  1: m=0;
      if(isleapyear(year)==1) m=6;break;
          
case 2:m=3;
    if(isleapyear(year)==1) m=2;break;[/color]    
case 3:  m=3;break;
case 4:  m=6;break;
case 5:    m= 1;break;
case 6:  m=4;break;
case 7:  m=6;break;
case 8:  m=2;break;
case 9:  m=5;break;
case 10:  m=0;break;
case 11:  m=3;break;
case 12:  m=5;break;
}
return m;
}
void main()
{ int day,year,month,century,total;
  cout<<"please enter the year,month,day:\n";
  cin>>year>>month>>day;
  century=getcenturyvalue(year);
  year=getyearvalue(year);
  month=getmonthvalue(month,year);
  total=day+month+year+century;
  total=total%7;
  if(total==0) cout<<"It is Sunday!\n";
  else if(total==1) cout<<"It is Monday!\n";
  else if(total==2) cout<<"It is Tuesday!\n";
  else if(total==3) cout<<"It is Wednesday!\n";
  else if(total==4) cout<<"It is Thursday!\n";
  else if(total==5) cout<<"It is Friday!\n";
  else cout<<"It is Saturday!\n";
}

回复列表 (共3个回复)

沙发

计算星期其实有一个公式的。
式子1:  days'  = (year-1)/4 + (year-1)/400 - (year-1)/100; ////多少个闰年
式子2:  days' += year;                                     ////加上年数
式子3:  days' += yearDay;/* yearDay表示一年当中的第几天 */ ////
公式 :   星期   = days' % 7;

可能这样算比您的算法要好些。其实这也很好理解:一年有365(365%7==1)天,所以每过一个平年,就相当于星期过了一天;如果是闰年,就相当于过了两天。这样,我们只要考虑到公元元年一共经过了多少个闰年(式子1)。再加上所有的年数(式子2)。在此基础上,加上一年中的天数(式子3), 然后 模7 得到的就是相当于公元1年1月1日过了的天数。再结合实际情况,就可以得到上面的式子3.
下面的代码是以前写的,应该可以参考。
[code=c]
#include <stdio.h>
#include <conio.h>

unsigned int static inline
s_is_leap_year (unsigned int year)
{                                                         /* 闰年? */ 
  return (year % 4U == 0U) &&  
         ((year % 100U != 0U) | (year % 400U == 0U));
}


unsigned int
get_yearDay (year, month, day)
    unsigned int year, month, day;
{                               /* month月day日在year年中是第几天? */
  static int t1 [ ] = 
    {0,  0,  31,  59,  90, 120, 151, 181, 212, 243, 273, 304, 334};
  unsigned int days;
  
  days  = s_is_leap_year (year) & (month > 2U);
  days += day + t1 [month];

  return days;
}


unsigned int
get_weekDay (year, month, day)
    unsigned int year, month, day;
{                                   /* year年month月day日是星期几? */
  unsigned int years, days;

  days  = year - 1U;
  years = year - 1U;
  
  days += get_yearDay (year, month, day);
  days += (years / 4U) + (years / 400U) - (years / 100U);

  return (days % 7U);
}


int main ( void )
{
  unsigned int year, month, day;
  unsigned int yearDay, weekDay;
  const char  *week_table [ ] =
    {"星期日","星期一","星期二","星期三","星期四","星期五","星期六"};

  puts  ( "请输入<年 月 日>: " );
  scanf ( "%u%u%u", &year, &month, &day );

  yearDay = get_yearDay (year, month, day);
  weekDay = get_weekDay (year, month, day);

  printf ( "%2u月%2u日在%04u年中是第%3u天,%s",
         month,   day,  year,    yearDay,  week_table[weekDay]);
         
  //getch ( );
  return 0;
}
[/code]

板凳

楼上算法有一个小BUG,公元没有0年,只有公元1年,同时1年1月1日也不是星期一。
同时,每年也不都是365天,有几年改过历法,多或者少了几天。

其时一般日期都从公元1970年以后开始算,1970年1月1日星期四,Thursday。
再简化一下,1901到2099年之间,所有闰年只需整除四。不需要对400和100判断。

3 楼

[quote]楼上算法有一个小BUG,公元没有0年,只有公元1年,同时1年1月1日也不是星期一。
同时,每年也不都是365天,有几年改过历法,多或者少了几天。

其时一般日期都从公元1970年以后开始算,1970年1月1日星期四,Thursday。
再简化一下,1901到2099年之间,所有闰年只需整除四。不需要对400和100判断。
[/quote]
1. 一般而言,公元好像没有0年,公元元年就是公元1年。

2. 事实上,在日历上确实有些年不是365或者366年。但如果采用格列高利历法的话年只只有2种情况365或者366天。在格列高利历法以前,儒略历用得比较多,这个历法总是4年一闰,不管其他,这样大约每400年将有3天的差距。格列高利历法在1582年最开始实行,把1582年10月4日的后一天调为1582年10月15日,这中间的10天被撤销了而使清除儒略历留下的日期偏差。英国好像是在1752年(9月2日之后就是9月14日)采用格列高利历法的,由于历史原因,美国也是把1752作为第一个采用格列高利历法的年份。现在很多计算机中都是把1752年看成转折,也就是说没有1752年9月3日~1752年9月13日这11天。

3.如果把每一天都当成一样来对待,格列高利历也是有误差的,每3000年左右将会差1天。还有就是地球公转周期总是有细微的偏差。润秒 可以解决这个问题。专门的组织在每个季度公布润秒数据,润秒总只会发生在每个季度的最后一天,并且润秒数是从0~2不等。

4.由于这样的原因,在使用格列高利历法以前,是很难定位一个日期的星期以及一年当中的天数,主要是看是那一年开始采用格列高利历法。而那段代码完完全全按照格列高利历法来计算,在使用格列高利历法以前的日期里,计算的结果基本上是错的。 如果考虑1752年9月14日以后可能还是正确的。

我来回复

您尚未登录,请登录后再回复。点此登录或注册