Skip to content

日期类的处理

一、闰年

闰年的详细定义:

  1. 年份非整百且能被4整除的为闰年。(如2004 年就是闰年、2005 年不是闰年)
  2. 年份能被 400 整除的是闰年。(如2000年是闰年,1900年不是闰年)
  3. 注意:能被100 整除的年份,必须要被 400 整除才是闰年。
c
/**
 * 闰年
 * @author  王铭颢
 * @Date  2022/11/20 16:15
 */

int is_leap_year(int year) {
    return year % 400 == 0 || (year % 100 != 0 && year % 4 == 0);
}

二、星期计算

蔡基姆拉尔森计算公式

假设星期为ww,年份为yy,月份为mm,日期为dd

w=(d+2*m+3*(m+1)/5+y+y/4-y/100+y/400)%7

然后把计算出来的ww加上1就是真正的星期几了。

每年的1、2月要当成上一年13、14月计算,上述的除法均为整除(地板除)。

三、代码

1、星期推算

已知1年1月1日是周一,求y年m月d日是周几?

1)推算法

cpp
/**
 * 星期的计算
 * @author  王铭颢
 * @Date  2022/11/20 22:55
 */
#include "iostream"

using namespace std;

string Week[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

int is_leap_year(int year) {
    return year % 400 == 0 || (year % 100 != 0 && year % 4 == 0);
}

int whatDay(int y, int m, int d) {
/*
 * 1 1 1是周一
 * 1900 1 1也是周一
 */
    int ans = 0;
    for (int i = 1; i < y; ++i) {
        ans += 365 + is_leap_year(i);
        ans %= 7;
    }
    for (int i = 1; i < m; ++i) {
        if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) {
            ans += 31;
        } else if (i == 2) {
            ans += 28 + is_leap_year(y);
        } else {
            ans += 30;
        }
        ans %= 7;
    }
    ans += d - 1;
    ans %= 7;
    return ans;
}

int main() {
    int y, m, d;
    cin >> y >> m >> d;
    cout << Week[whatDay(y, m, d)] << endl;
    return 0;
}

2)公式法

cpp
/**
 * 星期的计算公式
 * @author  王铭颢
 * @Date  2022/11/20 23:14
 */
#include "iostream"

using namespace std;

string Week[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};

int whatDay(int y, int m, int d) {
    if (m <= 2) {
        m += 12;
        y--;
    }
    return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
}

int main() {
    int y, m, d;
    cin >> y >> m >> d;
    cout << Week[whatDay(y, m, d)] << endl;
    return 0;
}

2、生命计算器

a年b月c日到d年e月f日共有多少天

cpp
/**
 * 生命计算器
 * @author  王铭颢
 * @Date  2022/11/20 23:28
 */

#include "iostream"

using namespace std;
int day[13] = {0, 31, 28, 31, 30, 31, 30,
               31, 31, 30, 31, 30, 31};

int main() {
    int a, b, c, d, e, f;
    cin >> a >> b >> c >> d >> e >> f;
    int ans = 0;
    for (;;) {
        if (a == d && b == e && c == f) break;
        else {
            c++;
            ans++;
        }
        day[2] = 28 + (a % 400 == 0 || (a % 100 != 0 && a % 4 == 0));
        if (c == day[b] + 1) {
            c = 1;
            b++;
        }
        if (b == 13) {
            b = 1;
            a++;
        }
    }
    cout << ans + 1 << endl;
    return 0;
}

3、恋爱纪念日

a年b月c日后的n天是哪天

cpp
/**
 * 恋爱纪念日
 * @author  王铭颢
 * @Date  2022/11/20 23:21
 */

#include "cstdio"

int day[13] = {0, 31, 28, 31, 30, 31, 30,
               31, 31, 30, 31, 30, 31};

int main() {
    int y, m, d, k;
    scanf("%d%d%d%d", &y, &m, &d, &k);
    for (int i = 0; i < k; ++i) {
        day[2] = 28 + (y % 400 == 0 || (y % 100 != 0 && y % 4 == 0));
        d++;
        if (d == day[m] + 1) {
            m++;
            d = 1;
        }
        if (m == 13) {
            m = 1;
            y++;
        }
    }
    printf("%04d-%02d-%02d", y, m, d);
    return 0;
}

Released under the MIT License.