prev up next   top/contents search

comp.lang.c FAQ 列表· 问题 20.31

Q如何根据日期找到星期几?


A这里有三种方法

  1. 使用mktimelocaltime(参见问题 13.13)。下面是一段计算 2000 年 2 月 29 日星期几的代码片段
    #include <stdio.h>
    #include <time.h>
    
    char *wday[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
    		"Thursday", "Friday", "Saturday"};
    
    struct tm tm;
    
    tm.tm_mon = 2 - 1;
    tm.tm_mday = 29;
    tm.tm_year = 2000 - 1900;
    tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
    tm.tm_isdst = -1;
    
    if(mktime(&tm) != -1)
    	printf("%s\n", wday[tm.tm_wday]);
    
    使用时mktime像这样,通常重要的是将tm_isdst设置为 -1,如所示(尤其是当tm_hour为 0 时),否则夏令时修正可能会将时间推移到午夜,进入另一天。
  2. 使用 Zeller 的同余公式,该公式指出,如果

    	J is the number of the century [i.e. the year / 100],
    	K the year within the century [i.e. the year % 100],
    	m the month,
    	q the day of the month,
    	h the day of the week [where 1 is Sunday];
    


    并且如果将一月和二月视为前一年的第 13 和 14 个月(影响 J 和 K);然后,格里高利历的 h 是以下总和的余数

    	q + 26(m + 1) / 10 + K + K/4 + J/4 - 2J
    


    除以 7,并且所有中间余数都被丢弃。[脚注] 翻译成 C 语言很简单
    	h = (q + 26 * (m + 1) / 10 + K + K/4 + J/4 + 5*J) % 7;
    
    (我们使用+5*J来解决这个问题,而不是-2*J来确保模运算符的两个操作数%都是正数;这个总偏置7*J显然不会改变最终值h,模 7)。
  3. 使用 Tomohiko Sakamoto 的这个优雅的代码
    int dayofweek(int y, int m, int d)	/* 0 = Sunday */
    {
    	static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
    	y -= m < 3;
    	return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
    }
    

另请参见问题 13.1420.32

参考文献:ISO Sec. 7.12.2.3
Chr. Zeller,“Kalender-Formeln”


prev up next   contents search
关于此 FAQ 列表   关于 Eskimo   搜索   反馈   版权

Eskimo North 托管