找到给定年份第0天的星期几的最简单算法是什么?

时间:2009-01-26 02:21:31

标签: algorithm date calendar

我想弄清楚某一年零日(1月1日)的一周中的哪一天。

到目前为止,我已经查看了维基百科页面“Calculating the day of the week”,但我想知道如果你只是想找到零日,那么是否有最简单的算法。

12 个答案:

答案 0 :(得分:15)

这是一个简单的单行。我使用Excel验证了1901-2200的所有年份,使用Python的datetime验证了1582-3000。

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

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

答案 1 :(得分:8)

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

答案 2 :(得分:8)

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;
}

答案 3 :(得分:3)

我发现这比维基百科上的文章更实用,但它仍然是通用的:

http://stason.org/TULARC/society/calendars/2-5-What-day-of-the-week-was-2-August-1953.html

答案 4 :(得分: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编写 不知道为什么它有效,但我发现这个算法深入谷歌搜索的内容,并迅速跳过它为我的项目。你在上面看到的是我必须为我在大学的java课程中所做的项目编写的方法,所以它是由我编写的,但算法不是我自己的。

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

  

让日期为DD / MM / CCYY(欧洲格式),其中DD是日期   月份,MM是月份,CC是世纪数字,YY是年份   在这个世纪内。所以威尔玛的生日是23/06/1994。从...开始   世纪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 =星期四。简单,   当你知道如何:-)
该算法归功于高斯。   是的,我知道犹太人和穆斯林等人有不同的日历和   我知道各种日历改革,所以这只适用于   现代基督教的标准化日期,不要去使用它   检查基督被钉十字架的那一天(小说?)甚至是乔的   诞生。

如果你不能做心算术(因此   在酒吧里喝啤酒)随意使用铅笔和纸(或者   计算器)。

答案 5 :(得分: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");
}

答案 6 :(得分:1)

MATLAB例程:

功能w = week_day(m,d,cy)

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

c = fix(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

冯成昌

答案 7 :(得分:0)

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

答案 8 :(得分: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是星期三等。

答案 9 :(得分:-1)

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

答案 10 :(得分:-1)

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

答案 11 :(得分:-1)

day = (((year - 1) * 365) + ((year - 1) / 4) - ((year - 1) / 100) + ((year) / 400) + 1) % 7;

鉴于这一年,这将找到1月1日的星期几,其中星期日为0,星期六为6