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 { |