LC1118 一月有多少天
LC1154 一年中的第几天
LC1360 日期之间间隔几天
LC1185 一周中的第几天
闰年
- 四年一闰,百年不闰,四百年再闰:
(year % 4 == 0 && year % 100 != 0) || year % 400 == 0 - 从公元1年开始的闰年个数:
year / 4 - year / 100 + year / 400 - 闰年的二月有29天,平年的二月有28天。
code
1 | class Solution { |
计算y-m-d自1-1-1的天数
不考虑历史因素(儒略历到格里高利历的更改)。认为1-1-1是第0天。
设该日期为:y-m-d:
1-1-1到y-1-1的左闭右开区间内的天数:- 不考虑平年闰年,则自
1-1-1起,到今年初y-1-1的左闭右开区间内共有365 * (y - 1)$天。 - 从
1-1-1到去年(y - 1年)共有leap = (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400个闰年。则应补上leap天。
- 不考虑平年闰年,则自
y-1-1到y-m-1的左闭右开区间内的天数:- 将平年每月的天数记录到数组中,为方便计算,前方留0:
mdays = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} - 则经过的天数为
accumulate(mdays.begin(), mdays.begin() + m)天。 - 如果今年是闰年,并且
m > 2,则应该补上1天。
- 将平年每月的天数记录到数组中,为方便计算,前方留0:
y-m-1到y-m-d的左闭右开区间的天数为d - 1天。
总计:1
2
3
4
5
6
7
8mkdays(int y, int m, int d)
{
return (365 * (y - 1))
+ (y - 1) / 4 - (y - 1) / 100 + (y - 1) / 400
+ accumulate(mdays.begin(), mdays.begin() + m, 0)
+ (((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) && m > 2)
+ d - 1;
}
天
即计算y-1-1到y-m-d经过的天数:
y-1-1到y-m-1的左闭右开区间内的天数:- 将平年每月的天数记录到数组中,为方便计算,前方留0:
mdays = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} - 则经过的天数为
accumulate(mdays.begin(), mdays.begin() + m)天。 - 如果今年是闰年,并且
m > 2,则应该补上1天。
- 将平年每月的天数记录到数组中,为方便计算,前方留0:
y-m-1到y-m-d的左闭右开区间的天数为d天。- 加上1天,因为
y-1-1是第1天,不是第0天。
code
1 | class Solution { |
计算两个日期的间隔,就是计算两个日期到1-1-1的天数差。
code
1 | class Solution { |
y-m-d是星期几
不考虑历史因素,只按照现行历法回推,1-1-1天是星期一。
因此日期y-m-d是星期几可以按下面的程序计算:
1 | int day_of_the_week = mkdays(y, m, d) % 7 + 1; |
code
1 | class Solution { |