1185. 一周中的第几天
给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。
输入为三个整数:day、month 和 year,分别表示日、月、年。
您返回的结果必须是这几个值中的一个 {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
。
约束条件
给出的日期一定是在 1971
到 2100
年之间的有效日期。
示例
Example 1:
Input: day = 31, month = 8, year = 2019
Output: "Saturday"
复制代码
Example 2:
Input: day = 18, month = 7, year = 1999
Output: "Sunday"
复制代码
Example 3:
Input: day = 15, month = 8, year = 1993
Output: "Sunday"
复制代码
题解
重要提示:
- 1970.12.31 是 Thursday,这个需要通过查日历得知,我感觉应该作为题目给出的条件之一;
- 闰年的定义是: 年份是400的倍数 或 年份是4的倍数且不是100的倍数;
- 闰年比普通年份多一天即
366
天;
题目约束年份是 1971
年到2100
年,那么我们计算给定日期到 1970.12.31
的天数 days
,那么 weekDay=(days+4)%7
即为当天是星期几(0为周日)。
我们再创建一个数组 weekDays=["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
那么 weekDays[weekDay]
即为最终答案。
举个例子: 如果给定day = 1, month = 1, year = 1971
,那么距离 1970.12.31
是days=1
,则结果为 weekDay=(1+4)%7=5
,即答案为weekDays[5]=Friday
。
那么如何计算给定日期到 1970.12.31
的天数 days
呢?可以分为以下三步:
- 计算指定
year
到1971年
之间的天数,如果是普通年份则每年365
天,如果是闰年则每年366
天; - 计算指定
month
到当年1月1日
之间的天数,其中1/3/5/7/8/10/12月
为31天
,2月
普通年份为28天
,闰年为29天
,其余月份为30天
; - 加上当月天数
day
;
上述三步的结果之和即为最终的 days
,则 weekDay=(days+4)%7
,答案即为weekDays[weekDay]
。
代码
public static String dayOfTheWeek(int day, int month, int year) {
String[] weekDays = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
int days = 0;
// 1.计算 year 到 1971年 之间的天数
for (int y = 1971; y < year; y++) {
days += isLeap(y) ? 366 : 365;
}
for (int m = 1; m < month; m++) {
days += getMonthDays(m, year);
}
days += day;
int weekDay = (days + 4) % 7;
return weekDays[weekDay];
}
private static boolean isLeap(int year) {
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
}
private static int getMonthDays(int month, int year) {
int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days = monthDays[month - 1];
// 如果是2月且是闰年则需要多加1天
return (month == 2 && isLeap(year)) ? days + 1 : days;
}
复制代码