日期类问题

计算两个日期之间的天数

leetcode 1360

请你编写一个程序来计算两个日期之间隔了多少天。

日期以字符串形式给出,格式为 YYYY-MM-DD,如示例所示。

  • 给定的日期是 1971 年到 2100 年之间的有效日期。

例如:

输入:date1 = "2019-06-29", date2 = "2019-06-30"
输出:1
    int toDay(const string& dateStr) {
        int year, month, day;
        sscanf(dateStr.c_str(), "%d-%d-%d", &year, &month, &day);
        if (month <= 2) {
            year--;
            month += 10;
        } else
            month -= 2;
        return 365 * year + year / 4 - year / 100 + year / 400
             + 30 * month + (3 * month - 1) / 5 + day  /* -584418 */;
    }
    int daysBetweenDates(string date1, string date2) {
        return abs(toDay(date1) - toDay(date2));
    }

方法二

日期一天一天递减效率不高。可以先按日,月,年的顺序依次直接转化为 1 日,1 月,1971 年,经过的天数可以直接计算得到。其中年份部分由于有闰年的因素,用 365 乘以年份之后,要再加上闰年的数量。闰年的数量不太好计算。我们采取以下策略:

1. 先加上所有模 4 为 0 的年份的数量。此时有些模 100 为 0 的不是闰年的年份被加上了。
2. 再减去所有模 100 为 0 的年份的数量。此时有些模 400 为 0 的是闰年的年份被减去了。
3. 再加上所有模 400 为 0 的年份的数量。完成。
    bool leap_year(int year) {
         return ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0));
    }
    int date_to_int(string date) {
        int year, month, day;
        sscanf(date.c_str(), "%d-%d-%d", &year, &month, &day);
        int month_length[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        int ans = day - 1;
        while (month != 0) {
            --month;
            ans += month_length[month];
            if (month == 2 && leap_year(year))
                ans += 1;
        }
        ans += 365 * (year - 1971);
        ans += (year - 1) / 4 - 1971 / 4;
        ans -= (year - 1) / 100 - 1971 / 100;
        ans += (year - 1) / 400 - 1971 / 400;
        return ans;
    }
    int daysBetweenDates(string date1, string date2) {
        return abs(date_to_int(date1) - date_to_int(date2));
    }

一周中的第几天

给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。

输入为三个整数:day、month 和 year,分别表示日、月、年。

您返回的结果必须是这几个值中的一个 {“Sunday”, “Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”}。

  • 给出的日期一定是在 1971 到 2100 年之间的有效日期。

例如:

输入:day = 31, month = 8, year = 2019
输出:"Saturday"

1582年10月4日后:w = [c/4]-2c+y+[y/4]+[26*(m+1)/10]+d-1) mod 7 ; or w + 7; 其中w为星期几,星期0为星期日,星期1为星期一,星期-1表示星期六,以此类推, 所以最后算出来 mod 7的结果如果是负数 需要+7变为非负; []表示取整; c为[year/100] 即 年份的前两位数; y为year%100 即 年份的后两位数; m为月数,注意:如果是1、2月需要把它当成上一年的13、14月,例如1997年1月28日应写成1996年13月28日; d为day;

    string dayOfTheWeek(int day, int month, int year) {
        vector<string> oneWeek{ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
        int y = year, m = month;
        if (month == 1 || month == 2)
        {
            --y;
            m += 12;
        }
        int cY = y / 100, yY = y - cY * 100;
        int indexWeek = (cY / 4 - 2 * cY + yY + yY / 4 + 26 * (m + 1) / 10 + day - 1) % 7;
        if (indexWeek < 0)
            indexWeek += 7;
        return oneWeek[indexWeek];
    }

月份表

map<string,int> str2int={
   {"January",1},
   {"February",2},
   {"March",3},
   {"April",4},
   {"May",5},
   {"June",6},
   {"July",7},
   {"August",8},
   {"September",9},
   {"October",10},
   {"November",11},
   {"December",12}
};

int int2str = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
]

一年中的第几天

leetcode

给你一个按 YYYY-MM-DD 格式表示日期的字符串 date,请你计算并返回该日期是当年的第几天。

通常情况下,我们认为 1 月 1 日是每年的第 1 天,1 月 2 日是每年的第 2 天,依此类推。每个月的天数与现行公元纪年法(格里高利历)一致。

示例:

输入:date = "2019-01-09"
输出:9
    int dayOfYear(string date) {
        int year = 0;
        for (int i = 0; i < 4; i++) 
            year = year * 10 + (date[i] - '0');
        bool flag = (year % 4 == 0) ? ((year % 100 == 0) ? (year % 400 == 0) : true) : false;
        int acumu[12] = { 0,31,59,90,120,151,181,212,243,273,304,334 };
        int month = (date[5] - '0') * 10 + (date[6] - '0');
        int day= (date[8] - '0') * 10 + (date[9] - '0');
        if (month < 3)return acumu[month - 1] + day;
        else return acumu[month - 1] + day + flag;
    }

打赏一下

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦