当前位置: 首页 > article >正文

蓝桥杯 Java B 组之日期与时间计算(闰年、星期计算)

Day 5:日期与时间计算(闰年、星期计算)

在编程竞赛中,日期和时间计算是常见考点,涉及 闰年判断、星期计算、日期间隔计算 等问题。本日的学习目标:

  • 判断闰年
  • 计算某个日期是星期几
  • 计算两个日期之间相差多少天
  • 处理日期边界情况


 一、闰年判断(Leap Year)

 1. 什么是闰年?

闰年(Leap Year)是 一个额外的 2 月 29 日,用来调整公历天文年的误差

判断规则

  1. 能被 4 整除,但不能被 100 整除
  2. 能被 400 整除

规则:

能被4整除但不能被100整除的年份是闰年。

能被400整除的年份也是闰年。

例子:2000年是闰年,1900年不是闰年。

例如:

  • 2000 年 是闰年(满足 400 整除)
  • 1900 年 不是闰年(满足 100 整除但不满足 400)
  • 2024 年 是闰年(满足 4 但不满足 100)


 2. 代码实现

import java.util.Scanner;



public class LeapYear {

    public static boolean isLeapYear(int year) {

        return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

    }



    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入年份:");

        int year = scanner.nextInt();



        if (isLeapYear(year)) {

            System.out.println(year + " 是闰年");

        } else {

            System.out.println(year + " 不是闰年");

        }

    }

}

时间复杂度 O(1),只进行几次取模计算,速度非常快。


 月份天数
各月天数:
1月(31天)、2月(闰年29天,平年28天)、3月(31天)、4月(30天)、5月(31天)、6月(30天)、
7月(31天)、8月(31天)、9月(30天)、10月(31天)、11月(30天)、12月(31天)。
public static int getDaysOfMonth(int year, int month) {

    int[] days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    if (month == 2 && isLeapYear(year)) return 29; // 闰年2月

    return days[month - 1]; // 月份从1开始,数组下标从0开始

}

 二、计算某个日期是星期几

 1. 计算方法

蔡勒公式(Zeller's Congruence)

W=(y+y/4−y/100+y/400+(13(m+1))/5+d)W = (y + y/4 - y/100 + y/400 + (13(m+1))/5 + d) % 7

参数解释

  • y = 年份(如果 m=1 或 m=2,则 y = y - 1)
  • m = 月份(1 月 和 2 月 视为 13 月 和 14 月,年份减 1)
  • d = 日期
  • W 代表星期:

0 - 星期六, 1 - 星期日, 2 - 星期一, 3 - 星期二, 4 - 星期三, 5 - 星期四, 6 - 星期五


2. 代码实现

import java.util.Scanner;



public class DayOfWeek {

    public static String getDayOfWeek(int year, int month, int day) {

        if (month == 1 || month == 2) {

            month += 12;  // 1月和2月看作前一年 13、14 月

            year--;

        }



        int w = (year + year / 4 - year / 100 + year / 400 + (13 * (month + 1)) / 5 + day) % 7;



        String[] days = {"星期六", "星期日", "星期一", "星期二", "星期三", "星期四", "星期五"};



        return days[w];

    }



    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入年份、月份、日期(用空格分隔):");

        int year = scanner.nextInt();

        int month = scanner.nextInt();

        int day = scanner.nextInt();



        System.out.println(year + "年" + month + "月" + day + "日 是 " + getDayOfWeek(year, month, day));

    }

}

时间复杂度 O(1),直接计算,不用循环。


 三、计算两个日期间隔天数

1. 思路

  1. 计算两个日期到 1970-01-01 的天数
  2. 相减得到间隔天数
  3. 需要考虑闰年和不同月份的天数


�� 2. 代码实现

import java.time.LocalDate;

import java.time.temporal.ChronoUnit;

import java.util.Scanner;



public class DateDifference {

    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);

        

        System.out.println("请输入第一个日期(格式:yyyy mm dd):");

        int year1 = scanner.nextInt();

        int month1 = scanner.nextInt();

        int day1 = scanner.nextInt();

        

        System.out.println("请输入第二个日期(格式:yyyy mm dd):");

        int year2 = scanner.nextInt();

        int month2 = scanner.nextInt();

        int day2 = scanner.nextInt();



        LocalDate date1 = LocalDate.of(year1, month1, day1);

        LocalDate date2 = LocalDate.of(year2, month2, day2);



        long daysBetween = ChronoUnit.DAYS.between(date1, date2);



        System.out.println("两个日期相差 " + Math.abs(daysBetween) + " 天");

    }

}

时间复杂度 O(1),使用 Java 8 LocalDate 处理日期,避免手动计算。


 四、蓝桥杯日期问题常考点

考点

典型题目

优化技巧

闰年判断

判断某年是否为闰年

直接使用 `if ((year % 4 == 0 && year % 100 != 0)

星期计算

给定年月日,计算星期几

使用 蔡勒公式

日期间隔

计算两个日期间隔天数

LocalDate 计算更高效

自定义日历

模拟日历程序

Java Calendar 或 LocalDateTime


 五、易错点总结

1. 忘记 1 月 和 2 月 的特殊处理

if (month == 1 || month == 2) {

    month += 12;

    year--;

}

2. 日期范围错误

LocalDate date1 = LocalDate.of(2022, 13, 15);  // ❌ 错误,月份超出范围

正确做法

LocalDate date1 = LocalDate.of(2022, 12, 15);  // ✅ 正确

3. ChronoUnit.DAYS.between() 使用错误

long days = ChronoUnit.DAYS.between(date2, date1);  // ❌ 可能得到负值

正确做法

long days = Math.abs(ChronoUnit.DAYS.between(date1, date2));  // ✅ 取绝对值



http://www.kler.cn/a/552618.html

相关文章:

  • 使用API有效率地管理Dynadot域名,参与过期域名竞价
  • 系统学习算法:专题十一 floodfill算法
  • 无人机避障——配置新NX
  • 出现 [ app.json 文件内容错误] app.json: 在项目根目录未找到 app.json (env: Windows,mp 解决方法
  • C#程序中进行打印输出文本
  • opencascade 源码学习找到edge对应的face BRepBuilderAPI-BRepBuilderAPI_FindPlane
  • 架构师面试(二):计算机编程基础
  • 极限网关核心架构解析:从 Nginx 到 INFINI Gateway 的演进
  • ABB机器人的二次开发
  • Ubuntu 下 nginx-1.24.0 源码分析 - ngx_palloc_block函数
  • golang面试题:两个interface{} 能不能比较?
  • 接口自动化框架篇:Pytest中的接口请求封装!
  • idea日常报错之UTF-8不可映射的字符
  • 游戏引擎学习第108天
  • MySQL数据库(3)—— 表操作
  • 深入解析LVS命令参数及DR模式下的ARP抑制原理
  • MybaitsPlus学习笔记(三)常用注解
  • 【科研绘图系列】R语言绘制时间序列图(time series plot)
  • 【Linux】Socket编程—TCP
  • 数据驱动的自动化本体构建过程包含3个阶 段