Calendar类日期设置进位问题

背景

        报表需求,需要传递每组数据中最小的日期,后台根据传递的最小日期,向前取参数传递的月份的上个月为结束时间的近五个月数据
例:参数传:2025/02,则需返回2025/01, 2024/12, 2024/11, 2024/10, 2024/09这五个年月数据。

实现方案

        先将请求参数按照/进行分割,得到年与月份,然后使用日历类Calendar,进行设置。获取到2025年1月31号23点59分59秒999毫秒的结束时间与
2024年9月30号0点0分0秒000毫秒的开始时间,然后按照开始时间与结束时间查询出该时段的所有数据,并按照年/月进行分组统计。

示例代码

public static Date getEndTime(String date, int months) {// 分割输入字符串为年和月String[] parts = date.split("/");int year = Integer.parseInt(parts[0]);int month = Integer.parseInt(parts[1]);// 创建 Calendar 实例(默认系统时区)Calendar calendar = Calendar.getInstance();// 设置年月(注意月份需减1)calendar.set(Calendar.YEAR, year);// 0-11 对应 1-12月calendar.set(Calendar.MONTH, month - 1);// 时间部分清零(时、分、秒、毫秒)calendar.set(Calendar.HOUR_OF_DAY, 23);calendar.set(Calendar.MINUTE, 59);calendar.set(Calendar.SECOND, 59);calendar.set(Calendar.MILLISECOND, 999);calendar.add(Calendar.MONTH, months);calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));return calendar.getTime();
}

上述代码单元测试结果,输出2025-01-21 23:59:59.999,符合预期

异常场景 

当执行这段代码的时间如果在月底,且当前月份的天数大于请求参数所在月份时,则会报错,如下,如果执行方法的时间为5月30号,请求参数"2025/02"时,则获取不到预期值:2025-01-21 23:59:59.999,返回数据仍为:2025-02-28 23:59:59.999.

问题原因分析

原始代码的执行流程

  1. Calendar.getInstance() sun.util.locale.provider.CalendarProviderImpl#getInstance 可以参考此方法

    • 默认获取当前时间:2025/05/30(假设调用时的时间)。

    • 此时 DAY_OF_MONTH=30

  2. 设置年月

    calendar.set(Calendar.YEAR, 2025);  // 2025年
    calendar.set(Calendar.MONTH, 1);    // 2月(Calendar.MONTH 是 0-11)
    • 此时日期变为 2025/02/30,但 2月没有30天,所以 Calendar 会自动调整到 2025/03/02(因为 2025年2月只有28天,30 - 28 = 2,所以变成3月2日)。

  3. calendar.add(Calendar.MONTH, -1)

    当前是 2025/03/02,减去1个月变成 2025/02/02(不是1月,因为3月减1是2月)。
  4. calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH))

    • 2月的最大天数是28(2025年不是闰年),所以最终日期是 2025/02/28 23:59:59.999

为什么返回的是2月的最后一天?

  • 关键问题calendar.set(Calendar.MONTH, 1) 设置2月时,由于当前 DAY_OF_MONTH=30(来自 Calendar.getInstance()),而2月没有30天,所以 Calendar 自动调整到了 3月2日

  • 然后 add(Calendar.MONTH, -1) 变成 2月2日,而不是预期的1月。

  • 最后设置月末日期,得到 2025/02/28 23:59:59.999

修复方案

public static Date getEndTime(String date, int months) {String[] parts = date.split("/");int year = Integer.parseInt(parts[0]);int month = Integer.parseInt(parts[1]);Calendar calendar = Calendar.getInstance();// 先清除时间部分,避免当前日期影响calendar.clear();  // 或 calendar.set(Calendar.DAY_OF_MONTH, 1);// 设置年月calendar.set(Calendar.YEAR, year);calendar.set(Calendar.MONTH, month - 1);  // 0-11// 加减月份calendar.add(Calendar.MONTH, months);// 设置月末最后一天 + 23:59:59.999calendar.set(Calendar.HOUR_OF_DAY, 23);calendar.set(Calendar.MINUTE, 59);calendar.set(Calendar.SECOND, 59);calendar.set(Calendar.MILLISECOND, 999);calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));return calendar.getTime();
}

 总结

  • 原始问题:由于 Calendar 初始化时携带了当前日期(如30日),而2月没有30天,导致自动调整到3月2日,再 -1 个月变成2月2日,最终返回2月末。

  • 修复方法:在设置年月前 清除 DAY_OF_MONTH(如 calendar.clear() 或 set(DAY_OF_MONTH, 1)),避免当前日期影响计算。

这样,传入 "2025/02" 和 -1 时,就能正确返回 2025年1月31日 23:59:59.999

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/83643.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

编程笔记---问题小计

编程笔记 qml ProgressBar 为什么valuemodel.progress / 100 在QML中,ProgressBar的value属性用于表示进度条的当前进度值,其范围通常为0到1(或0%到100%)。当使用model.progress / 100来设置value时,这样做的原因是为…

【STL】函数对象+常用算法

文章目录 STL- 函数对象函数对象函数对象使用 谓词一元谓词二元谓词内建函数对象算术仿函数关系仿函数 STL- 常用算法常用遍历算法for_eachtransform 常用查找算法findfind_ifadjacent_findbinary_searchcountcount_if 常用排序算法sortrandom_shufflemergereverse 常用拷贝和替…

[JVM] JVM内存调优

🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…

Spring Boot 从Socket 到Netty网络编程(下):Netty基本开发与改进【心跳、粘包与拆包、闲置连接】

上一篇:《Spring Boot 从Socket 到Netty网络编程(上):SOCKET 基本开发(BIO)与改进(NIO)》 前言 前文中我们简单介绍了基于Socket的BIO(阻塞式)与NIO(非阻塞式&#xff0…

python编写赛博朋克风格天气查询程序

工具介绍 这个天气查询工具是一个基于 Python 的桌面应用程序,使用了tkinter库来创建图形用户界面(GUI),并通过requests库调用 Open - Meteo API 获取天气数据。它具有赛博朋克风格的界面设计,提供了当前天气信息、15 天天气预报以及详细的天气数据展示,同时还包含温度趋…

从二叉树到 STL:揭开 set 容器的本质与用法

前言: 上次介绍完二叉搜索树后,更新中断了一段时间,先向大家致歉。最近学习状态有些起伏,但我正在努力调整,相信很快会恢复节奏。今天我们继续深入探讨——关联容器,它在算法和工程中都非常常见和重要。 1…

uv管理spaCy语言模型

本文记录如何在使用uv管理python项目dependencies时,把spaCy的模型也纳入其中. spaCy 一、spaCy简介 spaCy是一个开源的自然语言处理(NLP)库,它主要用于处理文本数据。它支持多种语言,包括英语、中文等。它是由Expl…

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…

Rust 学习笔记:Box<T>

Rust 学习笔记&#xff1a;Box Rust 学习笔记&#xff1a;Box<T\>Box\<T> 简介使用 Box\<T\> 在堆上存储数据启用带有 box 的递归类型关于 cons 列表的介绍计算非递归类型的大小使用 Box\<T\> 获取大小已知的递归类型 Rust 学习笔记&#xff1a;Box<…

英语写作中“不少于(小于)”no less than替代no fewer than的用法

no less than 1 liter of water&#xff0c;no fewer than 100 people 是我们的传统用法。现代英语有一个有趣的现象&#xff0c;就是less 代替fewer 形容可数名词&#xff0c;例如&#xff1a; Do you have 10 courses each week? No. We have less. 显然按严格语法应该是…

竞品分析六大步骤

一、引言 在产品打磨、市场推广或战略定位过程中&#xff0c;我们常常会面临一个关键任务——竞品分析。一份系统的竞品分析不仅能帮助我们知己知彼&#xff0c;优化产品策略&#xff0c;更能成为决策层制定方向的重要依据。竞品分析到底该怎么做&#xff1f;今天我将结合自己的…

【Java Web】9.Maven高级

&#x1f4d8;博客主页&#xff1a;程序员葵安 &#x1faf6;感谢大家点赞&#x1f44d;&#x1f3fb;收藏⭐评论✍&#x1f3fb; 文章目录 一、分模块设计与开发 1.1 介绍 1.2 实践 二、继承与聚合 2.1 继承 继承关系 版本锁定 2.2 聚合 2.3 继承与聚合对比 三、…

MySQL 全量、增量备份与恢复

一.MySQL 数据库备份概述 备份的主要目的是灾难恢复&#xff0c;备份还可以测试应用、回滚数据修改、查询历史数据、审计等。之前已经学习过如何安装 MySQL&#xff0c;本小节将从生产运维的角度了解备份恢复的分类与方法。 1 数据备份的重要性 在企业中数据的价值至关…

第六个微信小程序:教师工具集

源于工作需要&#xff0c;下面开始。 安装及使用 | Taro 文档 vscode 代码管理 git 辅助 开发技术如上&#xff1a; 1.开始创建模板 taro4.1.1 $ taro init teachers-tools 2.用vsocde开始吧。 选择 第二个文件夹找一。 (base) PS D:\react\teachers-tools> pnpm…

Linux 里 su 和 sudo 命令这两个有什么不一样?

《小菜狗 Linux 操作系统快速入门笔记》目录&#xff1a; 《小菜狗 Linux 操作系统快速入门笔记》&#xff08;01.0&#xff09;文章导航目录【实时更新】 Linux 是一个多用户的操作系统。在 Linux 中&#xff0c;理论上来说&#xff0c;我们可以创建无数个用户&#xff0c;但…

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …

服务器被攻击了怎么办

可以上一个高防IP或者AI云防护都是可以的。&#xff08;有效防御CC、APl接口、http、tcp、WEB应用扫描/爬虫、SYN、WAF、DDOS、UDP、入侵、渗透、SQL注入、XSS跨站脚本攻击、远程恶意代码执行、session fixation、Webshell攻击、恶意请求&#xff0c;恶意扫描、暴力破解、CSRF等…

【学习笔记】Circuit Tracing: Revealing Computational Graphs in Language Models

Circuit Tracing: Revealing Computational Graphs in Language Models 替代模型(Replacement Model)&#xff1a;用更多的可解释的特征来替代transformer模型的神经元。 归因图(Attribution Graph)&#xff1a;展示特征之间的相互影响&#xff0c;能够追踪模型生成输出时所采用…

灵活控制,modbus tcp转ethernetip的 多功能水处理方案

油田自动化和先进的油气行业软件为油气公司带来了诸多益处。其中包括&#xff1a; 1.自动化可以消除多余的步骤、减少人为错误并降低运行设备所需的能量&#xff0c;从而降低成本。 2.油天然气行业不断追求高水平生产。自动化可以更轻松地减少计划外停机时间&#xff0c;从而…

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…