【LeetCode解题报告】《算法基础006_日期算法》- Java

一、一周中的第几天

1.题目

1185.一周中的第几天

给你一个日期,请你设计一个算法来判断它是对应一周中的哪一天。
输入为三个整数:day、month 和 year,分别表示日、月、年。
您返回的结果必须是这几个值中的一个 {“Sunday”, “Monday”,
“Tuesday”, “Wednesday”, “Thursday”, “Friday”, “Saturday”}。
给出的日期一定是在 1971 到 2100 年之间的有效日期。

2.分析

这道题涉及到的知识点:

  1. 平闰年判断:一个年份,如果能被100整除且能被400整除,或者不能被100整除且能被4整除,那么这个年份就是闰年,否则为平年。
  2. 平年一年365天,2月有28天;闰年一年有366天,2月有29天。
  3. 这道题还有一个隐藏条件:1971年1月1日是星期五

思路:
(1)因为结果需要返回星期几的英文字符串,所以可以定义一个星期英文字符串的数组。
(2)由于最后求出是给定日期的星期相对于1971年1月1日星期的差值,所以需要再通过 (1971年星期下标 + 差值 - 1)% 7 来得到指定日期的星期下标(对7取余是因为有可能加上差值会超出数组最大长度)。

  1. 定义星期字符串数组 String[] weeks
  2. 循环累加1971年到 year - 1 年的天数
  3. 循环累加 year 年 1 月到 month - 1 月的天数
  4. 再累加 day后对7取余,得到从1971年1月1日起经过了n个完整的星期后,多出了几天
  5. 再通过这个差值确定在数组 String[] weeks 中的下标值

3.代码

    public String dayOfTheWeek(int day, int month, int year) {
        String[] weeks = {"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
        //每个月的天数
        int[] daysOfMonths = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        //计算给定日期离19710101经过了多少天
        int dates = 0;
        for(int i = 1971;i < year;i++){
            //闰年
            if(isLeapYear(i)){
                dates += 366;
                continue;
            }
            //平年
            dates += 365;
        }
        for(int i = 1;i < month;i++){
            //2月份闰年29天
            if(i == 2){
                dates += isLeapYear(year) ? 29 : 28;
                continue;
            }
            dates += daysOfMonths[i];
        }
        dates = (dates + day) % 7;
        //19710101是星期五,下标为4
        return weeks[(4 + (dates - 1)) % 7];
    }

    private boolean isLeapYear(int i){
        return (i % 400 == 0) || (i % 4 == 0 && i % 100 != 0);
    }

在这里插入图片描述

二、一年中的第几天

1.题目

1154.一年中的第几天

给你一个按 YYYY-MM-DD 格式表示日期的字符串 date,请你计算并返回该日期是当年的第几天。
通常情况下,我们认为 1 月 1 日是每年的第 1 天,1 月 2 日是每年的第 2 天,依此类推。每个月的天数与现行公元纪年法(格里高利历)一致。
date.length == 10
date[4] == date[7] == ‘-’,其他的 date[i] 都是数字。
date 表示的范围从 1900 年 1 月 1 日至 2019 年 12 月 31 日。

2.分析

思路:
(1)这道题其实就是累加当年1月到给定日期的天数,取二月份天数时注意平年闰年的判断即可。

3.代码

    public int dayOfYear(String date) {
        //每个月的天数
        int[] daysOfMonths = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        int year = Integer.parseInt(date.substring(0,4));
        int month = Integer.parseInt(date.substring(5,7));
        int day = Integer.parseInt(date.substring(8));
        
        int i,dates = 0;
        for(i = 1;i < month;i++){
            //2月份闰年29天
            if(i == 2){
                dates += isLeapYear(year) ? 29 : 28;
                continue;
            }
            dates += daysOfMonths[i];
        }
        return dates += day;
    }

    private boolean isLeapYear(int i){
        return (i % 400 == 0) || (i % 4 == 0 && i % 100 != 0);
    }

在这里插入图片描述

三、日期之间隔几天

1.题目

1360.日期之间隔几天

请你编写一个程序来计算两个日期之间隔了多少天。
日期以字符串形式给出,格式为 YYYY-MM-DD,如示例所示。
给定的日期是 1971 年到 2100 年之间的有效日期。

2.分析

思路:
(1)因为给定的两个日期 date1 和 date2 年份谁大谁小是不确定的,所以直接求两个日期之间的间隔天数会比较麻烦。
(2)所以转换一个思路:分别求两个日期相对于同一个日期的间隔天数,然后两个天数相减就是两个日期的间隔天数。
(3)因为这里给定的日期在1971年到2100年之间,所以只需要计算两个日期分别与1971年1月1日的间隔天数,再相减即可。

3.代码

    public int daysBetweenDates(String date1, String date2) {
        //每个月的天数
        int[] daysOfMonths = {0,31,28,31,30,31,30,31,31,30,31,30,31};
        //date1转换成数字
        int year1 = Integer.parseInt(date1.substring(0,4));
        int month1 = Integer.parseInt(date1.substring(5,7));
        int day1 = Integer.parseInt(date1.substring(8));
        //date2转换成数字
        int year2 = Integer.parseInt(date2.substring(0,4));
        int month2 = Integer.parseInt(date2.substring(5,7));
        int day2 = Integer.parseInt(date2.substring(8));
        //计算两个日期距离1971年1月1日有多少天
        int dates1 = dayFrom1971(daysOfMonths,year1,month1,day1);
        int dates2 = dayFrom1971(daysOfMonths,year2,month2,day2);
        return Math.abs(dates1 - dates2);
    }

    private int dayFrom1971(int[] daysOfMonths,int year,int month,int day){
        //计算指定日期离19710101经过了多少天
        int i,dates = 0;
        for(i = 1971;i < year;i++){
            if(isLeapYear(i)){
                dates += 366;
                continue;
            }
            dates += 365;
        }
        for(i = 1;i < month;i++){
            //2月份闰年29天
            if(i == 2){
                dates += isLeapYear(year) ? 29 : 28;
                continue;
            }
            dates += daysOfMonths[i];
        }
        dates += (day - 1);
        return dates;
    }

    private boolean isLeapYear(int i){
        return (i % 400 == 0) || (i % 4 == 0 && i % 100 != 0);
    }

在这里插入图片描述

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值