实战:求年月日时间前后遇到的坑和解决方式

这里写目录标题

  • 前言
    • 正确实例:
    • 错误实例:
  • 需求

前言

这周接到一个时间转换任务需要处理,本来没什么问题,后来完成后发现时间有偏差,又重写了一遍代码,感觉很有记录必要性,希望看过的小伙伴可以避坑。照例,先说结论。

正确实例:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.DATE_FORMAT);
LocalDateTime now = LocalDateTime.now();

错误实例:

Calendar calendar = Calendar.getInstance(); 

结果:如果我们使用了错误的工具类Calendar,求出的时间在时分秒中会有偏差,打到几小时,小到十几秒。这个时间的偏差是我们无法忍受的。

需求

这个工作是要求一个接口传输给我们一部分参数,然后根据参数求出对应的数据,比如昨天今天,三小时、天、月、年后等等。下面是代码实例,照例先放正确的,错误的留给大家参考。

//求出年月日小时对应要求的时间
public Intent dateForParams2(Intent intent, String time) {DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.DATE_FORMAT);LocalDateTime now = LocalDateTime.now();String endTime = now.format(formatter);// 将时间向前推移1小时if (CommonConstants.HeHaiTimeKey.HOUR_1.equals(time)) {now = now.minusHours(1);}if (CommonConstants.HeHaiTimeKey.HOUR_3.equals(time)) {now = now.minusHours(3);}if (CommonConstants.HeHaiTimeKey.HOUR_24.equals(time)) {now = now.minusDays(1);}if (CommonConstants.HeHaiTimeKey.HOUR_48.equals(time)) {now = now.minusDays(2);}if (CommonConstants.HeHaiTimeKey.HOUR_72.equals(time)) {now = now.minusDays(3);}// 将日期向前推移3天if (CommonConstants.HeHaiTimeKey.DAY_3.equals(time)) {now = LocalDateTime.of(now.minusDays(3).toLocalDate(),LocalTime.of(8, 0, 0)            // 设置为8点整);}if (CommonConstants.HeHaiTimeKey.DAY_7.equals(time)) {now = LocalDateTime.of(now.minusDays(7).toLocalDate(),LocalTime.of(8, 0, 0));}if (CommonConstants.HeHaiTimeKey.DAY_15.equals(time)) {now = LocalDateTime.of(now.minusDays(15).toLocalDate(),LocalTime.of(8, 0, 0));}if (CommonConstants.HeHaiTimeKey.DAY_30.equals(time)) {now = LocalDateTime.of(now.minusDays(30).toLocalDate(),LocalTime.of(8, 0, 0));}// 将月份向前推移3个月if (CommonConstants.HeHaiTimeKey.THREE_MONTH.equals(time)) {now = LocalDateTime.of(now.minusMonths(3).toLocalDate(),LocalTime.of(8, 0, 0));}if (CommonConstants.HeHaiTimeKey.HALF_YEAR.equals(time)) {// 将月份向前推移6个月now = LocalDateTime.of(now.minusMonths(6).toLocalDate(),LocalTime.of(8, 0, 0));}// 将年份向前推移1年if (CommonConstants.HeHaiTimeKey.ONE_YEAR.equals(time)) {now = LocalDateTime.of(now.minusYears(1).toLocalDate(),LocalTime.of(8, 0, 0));}if (CommonConstants.HeHaiTimeKey.THREE_YEAR.equals(time)) {now = LocalDateTime.of(now.minusYears(3).toLocalDate(),LocalTime.of(8, 0, 0));}if (CommonConstants.HeHaiTimeKey.FIVE_YEAR.equals(time)) {now = LocalDateTime.of(now.minusYears(5).toLocalDate(),LocalTime.of(8, 0, 0));}if (CommonConstants.HeHaiTimeKey.TEN_YEAR.equals(time)) {now = LocalDateTime.of(now.minusYears(10).toLocalDate(),LocalTime.of(8, 0, 0));}//设置早上8点if (CommonConstants.HeHaiTimeKey.TODAY.equals(time)) {now = LocalDateTime.of(now.toLocalDate(),          // 使用当前日期LocalTime.of(8, 0, 0)      // 设置为8点整);}if (CommonConstants.HeHaiTimeKey.YESTERDAY.equals(time)) {//减去1天now = LocalDateTime.of(now.minusDays(1).toLocalDate(),LocalTime.of(8, 0, 0));// 结束日期为今日8点整endTime = eightForNow2(0);}if (CommonConstants.HeHaiTimeKey.LAST_DAY.equals(time)) {//减去2天now = LocalDateTime.of(now.minusDays(2).toLocalDate(),LocalTime.of(8, 0, 0));// 结束日期为昨日8点整endTime = eightForNow2(1);}String startTime = now.format(formatter);log.info("输出开始时间:{}", startTime);intent.setStartTime(startTime);intent.setEndTime(endTime);return intent;
}/*** 求出早8点*/
public String eightForNow2(Integer day) {DateTimeFormatter formatter = DateTimeFormatter.ofPattern(CommonConstants.DATE_FORMAT);LocalDateTime now = LocalDateTime.now();if (day != null) {if (day == 0) {now = LocalDateTime.of(now.toLocalDate(),          // 使用当前日期LocalTime.of(8, 0, 0)      // 设置为8点整);} else {now = LocalDateTime.of(now.minusDays(day).toLocalDate(),LocalTime.of(8, 0, 0));}}return now.format(formatter);
}

这个没有集成一个工具类是因为需求开发时间小,而且要求时间短,再加上是使用频率低。有常用的可以集成到你们的时间工具类中。

-------------------------------错误-------------------------------

/*** 根据Params求出不同的时间*/
public Intent dateForParams(Intent intent, String time) {SimpleDateFormat format = new SimpleDateFormat(CommonConstants.DATE_FORMAT);Calendar calendar = Calendar.getInstance(); //获取日历实例String endTime = format.format(calendar.getTime());//后去结束时间calendar.setTime(date); //将当前时间设置给日历实例int hour = calendar.get(Calendar.HOUR_OF_DAY); // 获取当前的小时数// 将时间向前推移1小时if (CommonConstants.HeHaiTimeKey.HOUR_1.equals(time)) {if (hour < 1) {calendar.add(Calendar.DAY_OF_MONTH, -1); // 将日期向前推移1天hour += 24; // 计算出对应的小时数calendar.add(Calendar.HOUR_OF_DAY, hour - 1);} else {calendar.add(Calendar.HOUR_OF_DAY, -1);}}if (CommonConstants.HeHaiTimeKey.HOUR_3.equals(time)) {if (hour < 1) {calendar.add(Calendar.DAY_OF_MONTH, -1); // 将日期向前推移1天hour += 24; // 计算出对应的小时数calendar.add(Calendar.HOUR_OF_DAY, hour - 3);} else {calendar.add(Calendar.HOUR_OF_DAY, -3);}}if (CommonConstants.HeHaiTimeKey.HOUR_24.equals(time)) {calendar.add(Calendar.DAY_OF_MONTH, -1);}if (CommonConstants.HeHaiTimeKey.HOUR_48.equals(time)) {calendar.add(Calendar.DAY_OF_MONTH, -2);}if (CommonConstants.HeHaiTimeKey.HOUR_72.equals(time)) {calendar.add(Calendar.DAY_OF_MONTH, -3);}// 将日期向前推移3天if (CommonConstants.HeHaiTimeKey.DAY_3.equals(time)) {calendar.add(Calendar.DAY_OF_MONTH, -3);calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);}if (CommonConstants.HeHaiTimeKey.DAY_7.equals(time)) {calendar.add(Calendar.DAY_OF_MONTH, -7);calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);}if (CommonConstants.HeHaiTimeKey.DAY_15.equals(time)) {calendar.add(Calendar.DAY_OF_MONTH, -15);calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);}if (CommonConstants.HeHaiTimeKey.DAY_30.equals(time)) {calendar.add(Calendar.DAY_OF_MONTH, -30);calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);}// 将月份向前推移3个月if (CommonConstants.HeHaiTimeKey.THREE_MONTH.equals(time)) {calendar.add(Calendar.MONTH, -3);}if (CommonConstants.HeHaiTimeKey.HALF_YEAR.equals(time)) {// 将月份向前推移6个月calendar.add(Calendar.MONTH, -6);}// 将年份向前推移1年if (CommonConstants.HeHaiTimeKey.ONE_YEAR.equals(time)) {calendar.add(Calendar.YEAR, -1);}if (CommonConstants.HeHaiTimeKey.THREE_YEAR.equals(time)) {calendar.add(Calendar.YEAR, -3);}if (CommonConstants.HeHaiTimeKey.FIVE_YEAR.equals(time)) {calendar.add(Calendar.YEAR, -5);}if (CommonConstants.HeHaiTimeKey.TEN_YEAR.equals(time)) {calendar.add(Calendar.YEAR, -10);}//设置早上8点if (CommonConstants.HeHaiTimeKey.TODAY.equals(time)) {calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);}if (CommonConstants.HeHaiTimeKey.YESTERDAY.equals(time)) {//减去1天calendar.add(Calendar.DAY_OF_MONTH, -1);calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);// 结束日期为今日8点整endTime = eightForNow(null);intent.setEndTime(endTime);}if (CommonConstants.HeHaiTimeKey.LAST_DAY.equals(time)) {//减去2天calendar.add(Calendar.DAY_OF_MONTH, -2);calendar.set(Calendar.HOUR_OF_DAY, 8);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);// 结束日期为昨日8点整endTime = eightForNow(1);intent.setEndTime(endTime);}String startTime;Date dayTime = calendar.getTime();if (CommonConstants.HeHaiTimeKey.REAL_TIME.equals(time)) {startTime = endTime;} else {startTime = format.format(dayTime); //将时间格式化为字符串}log.info("输出开始时间:{}", startTime);intent.setStartTime(startTime);intent.setEndTime(endTime);return intent;
}/*** 求出早8点*/
public String eightForNow(Integer day) {Calendar calendar = Calendar.getInstance(); //获取日历实例calendar.setTime(date); //将当前时间设置给日历实例if (day != null) {calendar.add(Calendar.DAY_OF_MONTH, -day); //减去对应天数}calendar.set(Calendar.HOUR_OF_DAY, 8); //设置早上8点calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);Date yesterday8am = calendar.getTime(); //获取昨天早上8点的时间SimpleDateFormat format = new SimpleDateFormat(CommonConstants.DATE_FORMAT);String formattedDateTime = format.format(yesterday8am);log.info("输出开始时间:{}", formattedDateTime);return formattedDateTime;
}

Calendar是Java中处理日期和时间的类,它提供了各种实用方法来操作日历、时区和时间等信息。以前,Java的日期时间类主要是使用Date和SimpleDateFormat,但是这两个类存在一些问题,如线程不安全,可变性等,因此Java 1.1中引入了Calendar类来替代它们。
Calendar类是一个抽象类,不能直接创建对象,可以通过getInstance()方法获取它的实例。通过set()方法设置日期和时间信息,getTime()方法获取Date类型的时间,get()方法获取年月日等信息。
Calendar类提供了对时间进行加减的方法,add()方法用于加减某个时间单位,例如,可以使用add(Calendar.DATE, 1)增加一天,也可以使用add(Calendar.MONTH, -1)减少一个月。roll()方法则是这样做的一种变体,它只对指定的字段进行修改,而不会对较高的字段进行更改。 Calendar类也提供了很多有用的方法来操纵和显示日期和时间,如getFirstDayOfWeek()获取当前的星期起始日,getMinimum()获取给定日历字段的最小值等等。
尽管Calendar类有很多优点,它仍然没有解决Date类的基本问题。在Java 8中,LocalDateTime类被引入作为替代Calendar和Date的更简单、更灵活的实现。本地日期时间的类提供了Java程序员可以更自然地处理日期和时间的方法,避免了时间区的混淆和线程安全问题。

LocalDateTime是Java8新增加的一个日期时间类,代表的是一个不带时区的日期和时间,具有不可变性,用于处理本地日期和时间。它的实例可以存储到精确到纳秒的时间。
LocalDateTime的初始化可以通过now()调用获取当前的日期和时间,也可以通过of()方法创建指定的日期和时间。其中,now()方法的具体实现是通过系统时钟获取当前的时间,of()方法则接受七个参数,分别是年、月、日、时、分、秒、纳秒顺序。
LocalDateTime还提供了很多方法来操纵日期和时间,比如加减日期时间、计算日期之间的间隔、格式化日期时间等。这样可以很方便地进行日常的开发工作。对于需要考虑时区的应用来说,Java8还提供了ZonedDateTime类。
LocalDateTime是一种非常实用的日期和时间处理类,它可以满足大多数应用对日期和时间的需求。

上面都是一些官网给出的答案,由此我们也可以看出,使用LocalDateTime是更好的一种选择,还在用calender的可以尝试替换了,不要停留在旧时代里。

代码就不具体讲解了也不是很难,注释也挺多,有什么不懂得可以评论下方提出,看到后会抓紧回复的。

ps:有的小伙伴可能的确是刚接触,这里提供一个calender的示例,自己试着修改成LocalDateTime,前者你可以不会,后者不行哦。

public static void main(String[] args) throws ParseException {
String dateTimeString = “2023-06-13 02:00:00”;
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
Date date1 = format.parse(dateTimeString); // 解析为 Date 对象

Calendar calendar = Calendar.getInstance(); //获取日历实例
calendar.setTime(date1); //将当前时间设置给日历实例//这里零时转换可以忽略,LocalDateTime没有这方面的烦恼
int hour = calendar.get(Calendar.HOUR_OF_DAY); // 获取当前的小时数
if (hour < 1) { // 如果小时数小于1,则需要特殊处理calendar.add(Calendar.DAY_OF_MONTH, -1); // 将日期向前推移1天hour += 24; // 计算出对应的小时数
}
//calendar.set(Calendar.HOUR_OF_DAY, hour - 72); // 将时间向前推移1小时
calendar.add(Calendar.YEAR, -10); // 将年份向前推移10年Date yesterday8am = calendar.getTime();
String formattedDateTime = format.format(yesterday8am); //将时间格式化为字符串
System.out.println("输出结果:"+formattedDateTime); //输出结果

}

今天就到这里吧,感觉有用的小伙伴可以点个赞,你的支持就是我更新的最大动力!

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

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

相关文章

【TCP/IP】广播 - 定义、原理及编程实现

目录 广播 广播的原理及形式 广播的编程与实现 套接字选项设置 发送者 接收者 拓展资料 广播 广播(Broadcast)是指封包在计算机网络中传输时&#xff0c;目的地址为网络中所有设备的一种传输方式。这里所说的“所有设备”也被限定在一个范围之中&#xff0c;这个范围被称…

Python读写xml(xml,lxml)Edge 浏览器插件 WebTab - 免费ChatGPT

Python读写xml&#xff08;xml&#xff0c;lxml&#xff09;Edge 浏览器插件 WebTab - 免费ChatGPT XML一、xml文件创建方法一&#xff1a;使用xml.dom.minidom1、文件、标签的创建 方法二&#xff1a;使用ElementTree 二、xml文件修改1、修改标签内容&#xff0c;属性2、增加子…

2023年数字人产业发展趋势报告:好看的皮囊到有趣的灵魂

报告来源&#xff1a;腾讯研究院 报告看点&#xff1a;随着交互智能技术的加速发展&#xff0c;数字人正在从技术创新走向产业应用。 在腾讯2022数字生态大会腾讯云智能专场上&#xff0c;腾讯研究院、腾讯云智能、创业黑马经过产业研究、实地调研&#xff0c;共同提炼发布《数…

Keras-深度学习-神经网络-人脸识别模型

目录 模型搭建 模型训练 模型搭建 ①导入所需的库&#xff0c;导入了 Keras 和其他必要的库&#xff0c;用于构建和处理图像数据。 from keras.models import Sequential from keras.layers import Dense, Flatten, Conv2D, MaxPooling2D import os from PIL import Image …

三、决策树 四、随机森林

三、决策树1.决策树模型的原理1&#xff09;什么是决策树2&#xff09;决策树模型原理3.构建决策树的目的4&#xff09;决策树的优缺点 2.决策树的典型生成算法1&#xff09;常用的特征选择有信息增益、信息增益率、基尼系数2&#xff09;基于信息增益的ID3算法3&#xff09;基…

lenovo联想Yoga 13s 2021 AMD平台ACN版(82CY)原厂预装Win11系统镜像原装OEM恢复出厂状态

LENOVO联想笔记本电脑&#xff0c;Yoga 13s 2021 AMD平台ACN版(82CY)原装出厂Windows11系统&#xff0c;恢复原厂OEM预装专用系统 系统自带所有驱动、出厂主题壁纸LOGO、Office办公软件、联想电脑管家等预装程序 所需要工具&#xff1a;16G或以上的U盘 文件格式&#xff1a;…

重生之我测阿里云U1实例(通用算力型实例)

官方福利&#xff01;&#xff01;&#xff01;&#xff01;大厂羊毛你确定不薅&#xff1f;&#xff1f;&#xff1f; 参与ECSU实例评测&#xff0c;申请免费体验机会&#xff1a;https://developer.aliyun.com/mission/review/ecsu 参与ECSU实例评测&#xff0c;申请免费体验…

详细认识二叉树【图片+代码】

目录 一、树的概念及结构 1.1树的概念 1.2树的相关概念 1.3树的表示 1.4树在实际中的应用&#xff08;目录树&#xff09; 二、二叉树概念及结构 2.1概念 2.2特殊的二叉树 2.3二叉树的性质 2.4二叉树存储结构 三、二叉树的顺序结构及实现 3.1二叉树的顺序结构 3…

初探 C++ 标准库

有趣的重载 重载左移操作符&#xff0c;将变量或常量左移到一个对象中&#xff01; C 标准库 C 标准库并不是 C 语言的一部分 C 标准库是由类库和函数库组成的集合 C 标准库中定义的类和对象都位于 std 命名空间中 C 标准库的头文件都不带 .h 后缀 C 标准库涵盖了 C 库的功…

6、多层感知机:数值稳定性和模型初始化

1、数值稳定性 考虑一个具有 L L L层、输入 x \mathbf{x} x和输出 o \mathbf{o} o的深层网络。每一层 l l l由变换 f l f_l fl​定义&#xff0c;该变换的参数为权重 W ( l ) \mathbf{W}^{(l)} W(l)&#xff0c;其隐藏变量是 h ( l ) \mathbf{h}^{(l)} h(l)&#xff08;令 h …

人工智能(pytorch)搭建模型14-pytorch搭建Siamese Network模型(孪生网络),实现模型的训练与预测

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型14-pytorch搭建Siamese Network模型(孪生网络)&#xff0c;实现模型的训练与预测。孪生网络是一种用于度量学习&#xff08;Metric Learning&#xff09;和比较学习&#xff08;Compariso…

Windows环境本地部署Oracle11g r2实操手册

前言&#xff1a;一直在做其他测试&#xff0c;貌似都忘了Windows环境oracle安装&#xff0c;这是一个很早很早的安装记录了&#xff0c;放上来做个备录给到大家参考。 环境&#xff1a; &#xff08;都是常规系统及工具&#xff0c;官网度娘搜索即可下载测试学习&#xff09;…