DateUtils 和 LocalDateTime 工具类:日期时间的优雅处理!

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:掘金/C站/腾讯云/阿里云/华为云/51CTO(全网同号);欢迎大家常来逛逛,互相学习。

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  日期时间的处理是开发中常见且繁琐的任务,每次遇到都是要自己手动计算一遍,但无论是格式化日期,还是日期的加减运算,甚至日期比较、区间判断,身为开发都曾经历过因日期错误而导致的各种"崩溃"时刻。如果你还在使用 SimpleDateFormatCalendar,那你一定知道,它们的复杂性和潜在的错误几乎成了开发中的"噩梦"。更不用说,处理跨月、跨年和时区的问题,通常还得让你心力交瘁。

  今天,我们将一起深入探索如何通过 JDK 8 新引入的 java.time 包和 Apache 提供的 DateUtilsDateFormatUtils 来优雅地处理这些问题。使用这些工具类,你将能更加高效、简洁地处理日期时间问题,避免手动操作日期时产生的混乱和错误。

  本文不仅会深入探讨日期的加减、格式化、比较和区间判断,还会通过实际代码示例帮助你更好地理解这些工具类的强大功能。你不再需要依赖那些繁琐的 Calendar 方法,而是能通过简洁、直观的方式处理日期时间。

1. 日期加减与格式化:让日期操作变得轻松

使用 Apache DateUtils 进行日期加减

  纵观这几年开发之旅,日期加减是我们日常开发中非常常见的需求,比如计算未来某一天的日期、获取过去一段时间的日期,或者计算日期之间的差距。如果你还是依赖 Calendar 来进行这些操作,那么你可能会知道它的复杂性和容易出错的地方:例如跨月、跨年或者计算大于 30 天的月份时,总是容易出现意外。幸运的是,Apache Commons Lang 提供的 DateUtils 工具类,可以帮助我们简单地进行日期加减,避免了繁琐的计算。

  我们来看看如何通过 DateUtils 来进行日期加减的操作:

示例代码

java 复制代码
import org.apache.commons.lang3.time.DateUtils;
import java.util.Date;

/**
 * @Author ms
 * @Date 2025年6月22日20:43:49
 */
public class DateUtilsExample {
    public static void main(String[] args) {
        Date currentDate = new Date();
        System.out.println("当前时间: " + currentDate);

        // 日期加减操作
        Date nextDay = DateUtils.addDays(currentDate, 1);  // 加一天
        System.out.println("加一天后的时间: " + nextDay);

        Date previousMonth = DateUtils.addMonths(currentDate, -1);  // 减一个月
        System.out.println("减一个月后的时间: " + previousMonth);

        Date nextYear = DateUtils.addYears(currentDate, 1);  // 加一年
        System.out.println("加一年后的时间: " + nextYear);
    }
}

  通过 DateUtils.addDays()DateUtils.addMonths()DateUtils.addYears(),你可以快速实现日期的加减,无论是加一天、减一个月,还是加一年,代码非常简洁,功能强大。你不再需要考虑日期加减时的细节(如跨月、跨年等),DateUtils 会为你自动处理这些情况。

示例解析

  针对如上示例代码,这里我给大家详细的代码剖析下,以便于帮助大家理解的更为透彻,帮助大家早日掌握。

  如上这段 Java 程序的核心在于展示如何对日期对象 进行"加减"操作。它依赖的是一个第三方工具类 DateUtils,这个类属于 Apache Commons Lang 库,专门提供便捷的日期处理方法。

程序逻辑简述:

  1. 获取当前时间: 使用 Java 自带的 Date 类获取系统当前的日期和时间,并打印出来。

  2. 加一天: 调用 DateUtils.addDays(currentDate, 1),表示在当前日期的基础上加 1 天。

  3. 减一个月: 调用 DateUtils.addMonths(currentDate, -1),负数参数表示减去时间。

  4. 加一年: 调用 DateUtils.addYears(currentDate, 1),表示增加 1 年。

重要概念解析:

  • Date 是 Java 中较早期用于处理时间的类,但功能有限。
  • DateUtils 是一个辅助工具类,简化了日期加减的实现。
  • 这些方法都是"不可变操作 ":原始日期 currentDate 不会被修改,每次操作返回的是一个新的日期对象
  • 所有操作都围绕"当前时间"进行扩展或缩减。

运行结果展示

  根据如上测试用例,我本地演示结果展示如下,仅供参考哈,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

使用 DateFormatUtils 格式化日期

  日期的格式化是开发中常见的需求。无论是日志记录、数据库存储还是前端展示,日期的显示格式往往需要根据不同的需求进行转换。以前,开发者们通常使用 SimpleDateFormat 来格式化日期,但它的使用存在很多问题,特别是线程安全性问题,容易导致潜在的 bug。而 DateFormatUtils 通过其简洁且线程安全的接口,解决了这些问题。

示例代码

  我们来看看如何使用 DateFormatUtils 来格式化日期:

java 复制代码
import org.apache.commons.lang3.time.DateFormatUtils;
import java.util.Date;

/**
 * @Author ms
 * @Date 2025年6月22日20:43:49
 */
public class DateFormatExample {
    public static void main(String[] args) {
        Date currentDate = new Date();

        // 格式化为 yyyy-MM-dd
        String formattedDate = DateFormatUtils.format(currentDate, "yyyy-MM-dd");
        System.out.println("格式化后的日期: " + formattedDate);

        // 格式化为 yyyy-MM-dd HH:mm:ss
        String formattedDateTime = DateFormatUtils.format(currentDate, "yyyy-MM-dd HH:mm:ss");
        System.out.println("格式化后的日期时间: " + formattedDateTime);

        // 格式化为自定义格式
        String customFormattedDate = DateFormatUtils.format(currentDate, "EEEE, MMMM d, yyyy");
        System.out.println("自定义格式化后的日期: " + customFormattedDate);
    }
}

  在这个代码示例中,我们使用 DateFormatUtils.format() 方法将当前日期格式化为多种不同的格式。无论是标准的 yyyy-MM-dd 格式,还是包含时间的 yyyy-MM-dd HH:mm:ss 格式,或者自定义的 EEEE, MMMM d, yyyy 格式,DateFormatUtils 都能轻松处理。

示例解析

  针对如上示例代码,这里我给大家详细的代码剖析下,以便于帮助大家理解的更为透彻,帮助大家早日掌握。

  如上这段程序的核心目的是演示如何将当前系统时间格式化成各种不同的字符串形式,方便人类阅读或输出使用。

程序首先获取当前时间,接着依次将时间转换为三种格式:

  1. 日期格式(年月日) 将当前时间格式化为"年-月-日"的形式,例如"2025-06-22"。这是最基础的日期表达方式,通常用于展示日历时间或数据库记录中的日期字段。

  2. 完整时间格式(年月日 时分秒) 将时间进一步格式化为包含"小时:分钟:秒"的完整格式,例如"2025-06-22 20:43:49"。这是在记录日志或生成时间戳时常用的标准格式。

  3. 自定义英文格式 最后一个格式使用了英文的日期描述方式,例如"Sunday, June 22, 2025"。这个格式会输出星期几、月份的英文全称、几号以及年份,适合用于英文报告或国际化场景。

  整个程序借助了一个第三方工具类,该类可以快速将日期转换为字符串形式,而不需要手动创建格式化器,使用上更简洁、直观。通过设定不同的格式模板,程序可以灵活地满足各种日期显示需求。

运行结果展示

  根据如上测试用例,我本地演示结果展示如下,仅供参考哈,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

2. 日期比较与区间判断:精准控制日期的"战斗力"

使用 DateUtils 判断日期区间

  日期区间判断是开发中非常常见的需求,尤其是业务逻辑中涉及到有效期、任务时效等场景时。通过区间判断,我们可以判断某个日期是否在指定的区间内,是否在活动的有效期之内等。DateUtils 工具类为我们提供了非常简便的日期比较和区间判断方法。

示例代码

  下面的代码展示了如何判断一个日期是否在指定的区间内:

java 复制代码
import org.apache.commons.lang3.time.DateUtils;

import java.util.Date;

/**
 * @Author ms
 * @Date 2025年6月22日20:43:49
 */
public class DateRangeExample {
    public static void main(String[] args) {
        Date startDate = new Date();
        Date endDate = DateUtils.addDays(startDate, 5);  // 5天后的日期

        Date targetDate = DateUtils.addDays(startDate, 3);  // 3天后的日期

        // 判断目标日期是否在区间内
        boolean isInRange = DateUtils.isSameDay(targetDate, startDate) || (targetDate.after(startDate) && targetDate.before(endDate));
        System.out.println("目标日期是否在区间内: " + isInRange);
    }
}

  通过 DateUtils.isSameDay()DateUtils.after()DateUtils.before() 方法,我们可以非常简单地判断一个日期是否在区间内。相比手动编写复杂的日期计算和判断逻辑,DateUtils 极大地简化了这一过程。

示例解析

  针对如上示例代码,这里我给大家详细的代码剖析下,以便于帮助大家理解的更为透彻,帮助大家早日掌握。

  如上我写的这段程序的作用是:判断某个日期是否在指定的时间范围内。以下是纯文字解析:

  1. 时间设置

  程序一开始获取了当前时间作为起始日期,然后利用日期工具类的加法功能:

  • 生成一个5天后的日期,作为结束日期;
  • 生成一个3天后的日期,作为目标日期。

  这三者构成一个时间判断场景:判断目标日期是否落在起始日期和结束日期之间。

  1. 日期区间判断

  程序通过逻辑判断目标日期是否处于区间 [startDate, endDate)(左闭右开):

  • 首先检查目标日期是否与起始日期是"同一天";
  • 如果不是,再判断它是否在起始日期之后且在结束日期之前。

  最终判断结果会打印出来,显示"目标日期是否在区间内"。

  1. 适用场景

  这种逻辑常用于:

  • 判断某个操作是否在有效时间范围内;
  • 检查一个日期是否属于某个周期;
  • 时间窗口控制,如活动时间、限时任务等。
  1. 用到的工具类功能
  • addDays:对日期加减天数;
  • isSameDay:判断两个日期是否为同一天;
  • afterbefore:判断日期先后关系。

  总结来说,这段程序通过构建起始日期、结束日期与目标日期,并使用日期比较逻辑判断目标是否"在区间内",体现了日期范围判断的基本思想。

运行结果展示

  根据如上测试用例,我本地演示结果展示如下,仅供参考哈,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

使用 java.time 进行日期比较

  JDK 8 引入的 java.time 类库提供了更加直观和现代化的日期处理方式。通过 LocalDateTimeLocalDate 等类,我们能够轻松实现日期的比较与计算。它们的 API 设计非常清晰,使用起来比传统的 Calendar 类更简单。

示例代码

  下面是如何使用 java.time 进行日期比较的代码示例:

java 复制代码
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * @Author ms
 * @Date 2025年6月22日20:43:49
 */
public class LocalDateExample {
    public static void main(String[] args) {
        LocalDateTime currentDateTime = LocalDateTime.now();
        LocalDateTime futureDateTime = currentDateTime.plusDays(10);

        // 比较日期
        if (futureDateTime.isAfter(currentDateTime)) {
            System.out.println("目标日期在当前日期之后!");
        }

        // 判断是否同一天
        LocalDate today = LocalDate.now();
        if (today.isEqual(LocalDate.of(2025, 6, 22))) {
            System.out.println("今天就是目标日期!");
        }
    }
}

  通过 LocalDateTime.isAfter()LocalDate.isEqual() 等方法,我们可以轻松地比较两个日期的先后和相等情况。相比 Calendar 类,这种方式更加简洁、清晰。

示例解析

  针对如上示例代码,这里我给大家详细的代码剖析下,以便于帮助大家理解的更为透彻,帮助大家早日掌握。

  如上这段程序使用的是 Java 8 引入的新时间 API,重点展示了如何使用 LocalDateTimeLocalDate 进行日期时间的操作与比较。以下是纯文字解析:

  1. 获取当前日期时间

  程序首先获取当前的本地日期时间,表示"此刻"的年、月、日、时、分、秒等信息。

  1. 计算未来的时间

  通过在当前时间上加 10 天,生成一个"未来的时间点"。这是通过不可变操作完成的,也就是说,原始时间不会被修改,而是返回一个新的结果。

  1. 时间比较

  程序判断这个"未来的时间"是否在当前时间之后。由于是加了 10 天的时间,这个判断肯定为真,输出信息表明"目标日期在当前日期之后"。

  1. 判断是否是特定日期

  接下来,程序使用 LocalDate(只包含年月日,不含时间)获取今天的日期,并与一个固定的目标日期进行比较,这里目标日期是"2025 年 6 月 22 日"。

  如果两者相同,说明"今天就是目标日期",会打印相应的提示。

  1. 适用场景

  此类日期判断在实际开发中常用于:

  • 检查某个事件是否即将到来;
  • 比较时间先后顺序;
  • 判断当前是否为某个特定纪念日、截止日等。
  1. 新旧日期 API 差异

  相比旧的 Date 类和 Calendar 类,这里的 LocalDateTimeLocalDate 提供了更清晰、类型安全、不变性强的时间处理方式,推荐在现代 Java 项目中使用。

  总结来说,这段程序演示了通过 Java 8 时间类处理当前时间、未来时间的比较,以及判断是否为特定日期的典型用法。

运行结果展示

  根据如上测试用例,我本地演示结果展示如下,仅供参考哈,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

3. 替换 JDK 中复杂的 Calendar 使用

  在 JDK 1.8 之前,Calendar 类是处理日期和时间的主要工具,但它的 API 复杂且不直观。随着 JDK 8 引入 java.time,我们终于告别了复杂的 Calendar 使用,转向了更为简洁和现代化的日期处理工具类。例如,LocalDateLocalDateTime 提供了更直接、更易懂的 API,帮助我们更加轻松地操作日期和时间。

使用 LocalDateLocalDateTime 代替 Calendar

示例代码

java 复制代码
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * @Author ms
 * @Date 2025年6月22日20:43:49
 */
public class CalendarReplacementExample {
    public static void main(String[] args) {
        // 使用 LocalDate 获取当前日期
        LocalDate currentDate = LocalDate.now();
        System.out.println("当前日期: " + currentDate);

        // 使用 LocalDateTime 获取当前时间
        LocalDateTime currentDateTime = LocalDateTime.now();
        System.out.println("当前时间: " + currentDateTime);

        // 日期加减操作
        LocalDateTime newDateTime = currentDateTime.plusDays(7);  // 加7天
        System.out.println("加7天后的时间: " + newDateTime);
    }
}

  通过 LocalDateLocalDateTime,我们可以轻松获取当前日期和时间,并进行日期的加减操作,代码简洁且直观。

示例解析

  针对如上示例代码,这里我给大家详细的代码剖析下,以便于帮助大家理解的更为透彻,帮助大家早日掌握。

  这段程序展示了如何使用 Java 8 的新日期时间 API (LocalDateLocalDateTime) 来替代旧的 Calendar 或 Date 类进行时间操作。以下是纯文字解析:

  1. 获取当前日期

  程序首先使用 LocalDate.now() 获取当前日期,包含年、月、日信息,不含时间部分。适用于只关注日期的场景,比如节假日、生日等。

  1. 获取当前日期时间

  随后,使用 LocalDateTime.now() 获取当前的日期和时间,包含年、月、日、时、分、秒等信息。适用于需要精确时间的操作,如日志记录、时间戳生成等。

  1. 日期加减操作

  接着,程序在当前时间的基础上加了 7 天,得到一个新的日期时间值。这说明 LocalDateTime 支持链式方法调用来完成加减操作,如 plusDays() 表示加天数。

  这种操作是不可变的:原时间不会被修改,返回的是一个新的时间对象。

  1. 输出说明

  程序分别打印了当前的日期、时间,以及加 7 天之后的时间,展示出 Java 8 时间 API 的直观和清晰。

  1. 总体意义

  该程序的重点在于展示一种更现代、更安全、更简洁的方式来处理时间,尤其是相比于旧的 Calendar 类,LocalDateLocalDateTime

  • 不可变,线程安全;
  • 语义明确,API 易读;
  • 更容易进行链式时间计算。

  总结:这段程序清晰地表达了"获取当前时间"和"进行时间加法"的基本需求,是 java.time API 替代传统日期处理方式的典型示例。

运行结果展示

  根据如上测试用例,我本地演示结果展示如下,仅供参考哈,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

4. 流程图:日期时间的处理流程

  为了帮助大家理解日期时间的处理流程,下面我用 mermaid 语法绘制了一个简单的流程图,展示不同日期操作的处理路径:

  这个流程图展示了从获取当前日期到各种操作的路径。通过选择不同的操作,你可以轻松地使用相应的工具类来处理日期和时间。

总结

  通过本文的讲解,我们可以看到,Apache DateUtilsDateFormatUtils 和 JDK 8 中的 java.time 工具类如何帮助我们简化日期时间的处理。从日期加减到格式化,从日期比较到区间判断,这些工具类都让我们能够轻松应对日期时间的各种需求。

  掌握这些工具类,能够让我们的代码更加简洁和高效,减少因日期时间错误导致的 bug。如果你还在使用繁琐的 Calendar 或者手动操作日期时间,那么赶紧尝试这些新的工具类吧!它们不仅能提高你的开发效率,还能让你在日期时间的处理中游刃有余。

... ...

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

... ...

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。 ⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

相关推荐
葫芦和十三1 天前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp1 天前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑1 天前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯1 天前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan1 天前
多Agent之间的区别
后端
青石路1 天前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充1 天前
1.面向对象设计思想
后端
IT_陈寒1 天前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro1 天前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗1 天前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端