给定一个日期,C++ 中的什么算法计算星期几(作为数字)? [已关闭]

问题描述 投票:0回答:1

给定一个

year
month
(1-12) 和
day
(1-31) 形式的日期,C 或 C++ 甚至 Python 中的什么算法计算星期几(如一个数字)?

下面你会发现我正在使用的手动方法。

我正在尝试编码,但看起来有点复杂。也许很容易把东西放在一起,但我希望期待 C 语言或 C++ 甚至 Python 的详细算法,以便我可以以编程方式可视化这个概念。

详细信息基于年、月、年所使用的算法和代码。 月

奇数天数

一月

3

二月(平日/闰月)

(0/1)

三月

3

四月

2

五月

3

六月

2

七月

3

八月

3

九月

2

十月

3

十一月

2

十二月

3

。闰年: 要检查非百年纪念年是否为闰年,我们将其除以 4。如果余数为 0,则该年为闰年。例如,2016 mod 4 = 0。因此,我们可以安全地推断出 2016 年是闰年。 要检查百年纪念年是否为闰年,我们将其除以 400。如果余数为 0,则该年为闰年。例如,1700 mod 400 = 100。因此,这不是闰年。但是 1600 mod 400 = 0。因此,我们可以安全地推断 1600 是闰年。

不。天数和日期

0 = 太阳

1 = 星期一

2 = 星期二

3 = 星期三

4 = 星期四

5 = 星期五

6 = 星期六

1947 年 8 月 16 日是什么日子? 解决方案:

1600 将有 0 个奇数天。 300年会有1个奇数日。现在,在接下来的 46 年里,我们将有 35 个平年和 11 个闰年。 => 奇数天数 = (35 x 1) + (11 x 2) = 35 + 22 = 57 mod 7 = 1 奇数天 迄今为止奇数天总数 = 1 + 1 = 2 一月奇数天数 = 31 mod 7 = 3 2 月奇数天数(1947 年为非闰年)= 28 mod 7 = 0 3 月奇数天数 = 31 mod 7 = 3 4 月奇数天数 = 30 mod 7 = 2 5 月的奇数天数 = 31 mod 7 = 3 6 月的奇数天数 = 30 mod 7 = 2 7 月的奇数天数 = 31 mod 7 = 3 截至 1947 年 8 月 16 日的奇数天数 = 16 mod 7 = 2 所以,奇数天总数 = 2 + 3 + 0 + 3 + 2 + 3 + 2 + 3 + 2 = 20 mod 7 = 6 因此,1947 年 8 月 16 日是星期六(奇数天 = 6 => 星期六)

c++ algorithm calendar
1个回答
-1
投票
泽勒同余

您询问的是一种计算给定日期是星期几的算法。

因此,1947 年 8 月 16 日是星期六(奇数天 = 6 => 星期六)

Zeller 的同余式正是您所需要的:

来自免费百科全书维基百科

Zeller 的同余 是 Christian Zeller 在 19 世纪设计的一种算法,用于计算任何儒略历或公历日期的星期几。可以认为是基于儒略日和日历日期之间的转换。

这是我对泽勒同余的 C++ 实现。

int ISO_8601_day_of_week(int const year, int const month, int const day)
{
    // ISO week date Day-of-Week d (1 = Monday to 7 = Sunday)
    // https://datatracker.ietf.org/doc/html/rfc3339#appendix-B
    //
    // Zeller's congruence
    // The formula used here is adapted from the Common Simplification 
    // described on Wikipedia:
    // https://en.wikipedia.org/wiki/Zeller's_congruence#Common_simplification
    //
    // That formula produces h between 0 and 6, with 0 = Saturday, 
    // 1 = Sunday, etc.
    // 
    // A further adjustment converts h into d, an an ISO 8601 week date 
    // Day-of-Week (1 = Monday to 7 = Sunday).
    // https://en.wikipedia.org/wiki/Zeller's_congruence#Formula
    // 
    // The initial adjustment effectively turns the last day 
    // of February into the last day of the year.
    check_date(year, month, day);
    int const
        y{ month < 3 ? year - 1 : year },                     // subtract 12 months
        m{ month < 3 ? month + 12 : month },                  // add 12 months
        q{ day },                                             // q = day of month
        h{ (q + 13 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 },  // 0 to 6 = Saturday to Friday
        d{ (h + 5) % 7 + 1 };                                 // 1 to 7 = Monday to Sunday
    return d;
}

函数

void check_date(int const y, int const m, int const d)
验证
y
m
d
,如果它们不形成有效日期,则抛出
std::invalid_argument
对象。为了简洁起见,省略了它的定义。

这是一个简短的驱动程序,我用来演示功能

ISO_8601_day_of_week

std::string day_name(int const y, int const m, int const d)
{
    switch (ISO_8601_day_of_week(y, m, d)) 
    {
    case 1: return "Monday";
    case 2: return "Tuesday";
    case 3: return "Wednesday";
    case 4: return "Thursday";
    case 5: return "Friday";
    case 6: return "Saturday";
    case 7: return "Sunday";
    default: return "[unknown]";
    }
}
int main()
{
    std::cout << "Question: What day of the week was 1947-Aug-16?"
        "\nAnswer: " << day_name(1947, 8, 16) << "\n\n";
    return 0;
}

输出:

Question: What day of the week was 1947-Aug-16?
Answer: Saturday
© www.soinside.com 2019 - 2024. All rights reserved.