首页 > 技术文章 > C++判断闰年&日期之差&给定日期求星期几

xkxf 2021-02-25 15:30 原文

判断闰年

地球绕太阳转一周的时间实际是365天5小时48分46秒。算下来,每四年会多出来一天,所以加到那一年的二月。但是这样算,又多算了一点点时间。于是,又规定,整百的年份计算闰年除以400。这样,我们的历法才能最大程度的和地球绕太阳转契合。

总之:非整百年份除以4无余数;整百年份除以400无余数

即:x % 100 != 0 && x % 4 == 0 || x % 400 == 0

计算日期差

思路是,先算出每一天距离0000年1月1日的天数。然后作差计算。

#include <cstdio>
#define IS_LEAP_YEAR(x) x % 100 != 0 && x % 4 == 0 || x % 400 == 0 ? 1 : 0  

int dayOfMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
struct Date {
    int y;
    int m;
    int d;
    void nextDay() {
        d++;
        if (d > dayOfMonth[m]) {
            d = 1;
            m++;
            if (m > 12) {
                m = 1;
                y++;
                if (IS_LEAP_YEAR(y)) {
                    dayOfMonth[2] = 29;
                } else {
                    dayOfMonth[2] = 28;
                }
            }
        } 
    }
};

int date2day[5000][13][32]; // 该数组作用——将特定日期转化距离 0000-01-01 的天数 
int main()
{    
    // 初始化 
    Date tmp = {0, 1, 1};
    int cnt = 1;
    date2day[tmp.y][tmp.m][tmp.d] = cnt++;
    
    while (tmp.y < 5000) {
        tmp.nextDay();
        date2day[tmp.y][tmp.m][tmp.d] = cnt++;
    }
        
    // 计算日期差 
    int y1, m1, d1;
    int y2, m2, d2;    
    scanf("%4d%2d%2d", &y1, &m1, &d1);
    scanf("%4d%2d%2d", &y2, &m2, &d2);
    
    int result = date2day[y1][m1][d1] - date2day[y2][m2][d2];
    if (result < 0) result = -result;
    result ++;
    
    printf("%d\n", result);
    
    return 0;
} 

给定日期求星期几

例如输入 5 February 2021

输出 Friday

#include <cstdio>
#include <cstring>
using namespace std;

int daysOfMonth[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool isLeapYear(int year) {
    return year % 100 != 0 && year % 4 == 0 || year % 400 == 0;    
}
struct Date {
    int y;
    int m;
    int d;
    int xingQi; 
    void nextDay() {
        d++;
        
        xingQi++;
        if (xingQi > 7) xingQi = 1;
        
        if (d > daysOfMonth[m]) {
            d = 1;
            m++;
            if (m > 12) {
                m = 1;
                y++;
                if (isLeapYear(y)) {
                    daysOfMonth[2] = 29;
                } else {
                    daysOfMonth[2] = 28;
                }
            }
        } 
    }
    
    void preDay() {
        d--;
        
        xingQi--;
        if (xingQi < 1) xingQi = 7;
        
        if (d < 1) {
            m--;
            if (m < 1) {
                m = 12;
                y--;
                if (isLeapYear(y)) {
                    daysOfMonth[2] = 29;
                } else {
                    daysOfMonth[2] = 28;
                }                
            }
            d = daysOfMonth[m];
        }         
    }
};

char int2xingQi[8][20] = {
    "",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
    "Sunday",
};

char charMs[13][20] = {
    "",
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December",
};

int charM2intM(char* charM) 
{
    for (int i = 1; i != 13; ++i) {
        if (strcmp(charM, charMs[i]) == 0) return i;
    }
    return -1;
}

int dateCmp(int y1, int m1, int d1, int y2, int m2, int d2)
{
    // 负数则 1 < 2 ,零则 1 = 2 ,正数则 1 > 2
    return y1 * 10000 + m1 * 100 + d1 - (y2 * 10000 + m2 * 100 + d2);
}

int main()
{
    // 给定日期求星期几
    // 已知2021年2月26日是星期五
    
    // 1.初始化 
    Date tmp = {2021, 2, 26, 5};

    // 2.输入
    int y, intM, d;
    char charM[20];
    
    scanf("%d %s %d", &d, charM, &y);
    intM = charM2intM(charM);
    
    // 3.计算 
    while (dateCmp(tmp.y, tmp.m, tmp.d, y, intM, d) < 0) tmp.nextDay();
    while (dateCmp(tmp.y, tmp.m, tmp.d, y, intM, d) > 0) tmp.preDay();

    // 4.输出
    printf("%s\n", int2xingQi[tmp.xingQi]);
    return 0;
} 

 

推荐阅读