12

我试图弄清楚给定年份的第 0 天(1 月 1 日)的星期几。

到目前为止,我已经查看了 Wikipedia 页面“计算星期几”,但我想知道如果您只是想找到零天,是否有最简单的算法。

4

11 回答 11

18

这是一个简单的单线。我已经使用 Excel 验证了 1901-2200 年的所有年份,以及使用 Python 的 1582-3000 年的datetime.

dayOfWeek = (year*365 + trunc((year-1) / 4) - trunc((year-1) / 100) +
             trunc((year-1) / 400)) % 7

这将使星期几为 0 = 星期日,6 = 星期六。这个结果可以很容易地通过在模 7 之前或之后添加一个常数来调整。例如,为了匹配 Python 的 0 = Monday 的约定,在模之前添加 6。

于 2009-01-26T06:39:43.370 回答
11
int dayofweek(y, m, d)      /* 0 = Sunday */
int y, m, d;                /* 1 <= m <= 12,  y > 1752 or so */
{
    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;
}
于 2009-05-25T05:42:57.583 回答
8

大多数语言都提供了表示和操作日期的工具......我会依赖这些工具而不是实现一些(可能不完整的)算法。

于 2009-01-26T02:31:28.600 回答
3
day = (((year - 1) * 365) + ((year - 1) / 4) - ((year - 1) / 100) + ((year) / 400) + 1) % 7;

给定年份,这将找到 1 月 1 日的星期几,其中星期日是 0,星期六是 6

于 2013-04-30T21:54:08.200 回答
2
public String DayOfWeek()
{
    int dayofweek;
    int c,y,m,d; 
    int cc,yy;
    String dayString;
    //Im using the guassian algorithm for finding day of the week 
    cc = year/100;
    yy = year - ((year/100)*100);

    c = (cc/4) - 2*cc-1;
    y = 5*yy/4;
    m = 26*(month+1)/10;
    d = day;

    dayofweek = (c+y+m+d)%7;

    switch(dayofweek)
    {
        case 0: dayString = "Sunday";
        break;
        case 1: dayString = "Monday";
        break;
        case 2: dayString = "Tuesday";
        break;
        case 3: dayString = "Wednesday";
        break;
        case 4: dayString = "Thursday";
        break;
        case 5: dayString = "Friday";
        break;
        case 6: dayString = "Saturday";
        break;
        default: dayString = "Sorry Could not compute month :(";   
    }

    return dayString;
}

上面的代码是用 Java 编写的,

不知道为什么会起作用,但我在 Google 搜索的深处发现了该算法,并迅速将其用于我的项目。你在上面看到的是我必须为我在大学 Java 课上做的一个项目编写的方法,所以它是我写的,但算法不是我自己的。

如果时间,这种方法保证 100% 有效,我在整个历史中尝试了多天并查找它们以确认正确的答案是通过这种方法找到的答案。

让日期为 DD/MM/CCYY(欧洲格式),其中 DD 是月份中的日期,MM 是月份,CC 是世纪数字,YY 是世纪内的年份。所以威尔玛的生日是 1994 年 6 月 23 日。从世纪 CC 位开始,计算 CC/4 - 2*CC-1 并记住结果。对于本练习中的所有除法,丢弃任何剩余部分,只保留整个部分。因此,在我们的示例中,这是 19/4=4 减去 2*19=38 减去 1,得出负 35。

现在,使用年份 YY,计算 5*YY/4。在此示例中,即 5*94 = 470/4 = 117,丢弃余数。将此添加到我们现有的结果中得到 117-35 = 82。

使用月份 MM,计算 26*(MM+1)/10。在我们的示例中,这是 26*7 = 182 / 10 = 18,再次丢弃余数。将此添加到我们的运行总数中,得到 82+18 = 100。

最后只添加一天DD。这里 100 + 23 = 123。

现在将结果除以 7,只保留余数;这里 123(mod 7) = 4。把星期日算为零,星期一 = 1 等等,我们得到 4 = 星期四。很容易,当你知道怎么做的时候:-)

该算法归功于高斯。是的,我知道犹太人和穆斯林等人有不同的日历,我也知道各种日历改革,所以这只适用于现代基督教标准化的日期,不要用它来检查基督受难的日子( -小说?)甚至乔叟的出生。

如果你不能像心算一样做到这一点(因此在酒吧赢得啤酒),请随意使用铅笔和纸(或计算器)。

于 2012-09-28T22:10:47.130 回答
1
     #!/usr/local/bin/perl 
     use integer
     %day=                 (0=>Sunday,1=>Monday,2=>Tuesday,3=>Wednesday,4=>Thursday,5=>Friday,6=>Saturday);
     print("entered date is");
     $day=30;
     $month=11;
     $year=2680;
     $x=&day_of_week($year,$month,$day);
     if($day>31||$month>12)
{
    print("this date doesn't exist \n");
    exit;
}

    if($year%400 ==0 || ($year%100 != 0 && $year%4 == 0))
{
    if($day>29&&$month==2)
    {
        printf("this date dosen't exist \n");
        exit;
    }
}
   if($month==(4,6,9,11)&&$day>30)
{
        printf("this date dosen't exist \n");
        exit;
}


     sub day_of_week{
my ($year,$month,$day)=@_;
print("yy/mm/dd: $year/$month/$day\n");
my  $a=(14-$month)/12;
my  $y=$year-$a;
my  $m=$month+12*$a-2;
my  $d=($day+$y+$y/4-$y/100+$y/400+31*$m/12)%7;
return $d;
}
if(exists($day{$x}))
{
    print("$day{$x}\n");
}
else
{
    print("invalid date entered\n");
}
于 2013-03-11T09:59:22.430 回答
1

MATLAB 程序:

函数 w = week_day(m,d,cy)

如果 m > 2,则 m = m-2;否则,m = m+10;cy = cy-1;结尾;

c = 修复(cy/100);y = mod(cy,100);

w = mod(d+fix(m*2.59)+fix(y*1.25)+fix(c*5.25),7);


诀窍是将 3 月 1 日作为一年的第一天。不管日期是否在闰年。

例子:

   w = week_day(01,23,2016)  --->   w = 6 {Sat)    Today
   w = week_day(12,31,1999)  --->   w = 5 {Fri)    
   w = week_day(01,01,2000)  --->   w = 6 {Sat)
   w = week_day(02,28,1900)  --->   w = 3 {Wed)    not leap year
   w = week_day(03,01,1900)  --->   w = 4 {Thu)
   w = week_day(02,29,2000)  --->   w = 2 {Tue)      leap year
   w = week_day(03,01,2000)  --->   w = 3 {Wed)

请参阅 Mathwork 文件交换文件 ID #54784

冯成昌

于 2016-01-23T19:50:21.503 回答
0

维基百科页面底部的“计算星期几”给出了您需要的规则。您还可以通过硬编码月份和月份的日期来简化 Zeller 的一致性。

于 2009-01-26T02:27:14.833 回答
0

年份以 28 年为周期重复。将年份除以 28 并返回相应的星期几(星期几值存储在数组/向量中)。这将是最快和最简单的算法。但是对于阅读代码的人来说,这个算法根本不清楚。您的选择取决于您想要快速、简单还是“明确正确”。

于 2009-01-26T02:56:52.870 回答
0

如果日期是 DD/MM/CCYY,您需要计算给定日期的日期。然后使用给定的公式 [{(CC/4)-2*CC -1}+(YY*5/4)+{(MM+1)*26/10} + DD]= x, x/7=Y其中 Y 是余数,其中 Y 可以是 0、1、2、3、4、5、6。其中 0 可以代表星期日,1 代表星期一,2 代表星期二,3 代表星期三等等。

于 2014-01-16T13:24:58.093 回答
-1

您可以始终保留参考日期,然后添加一年中的天数(mod 7)以保持运行记录,但就像 Zach 所说,使用内置函数会更容易。

于 2009-01-26T02:33:42.510 回答