在 Java 8 正式发布之前,开发者处理日期时间逻辑时,长期依赖 java.util.Date、java.util.Calendar 以及 java.text.SimpleDateFormat 这几套核心工具。这些 API 自 JDK 1.0 时代便已存在,伴随 Java 走过了十余年的发展历程,但随着软件系统的复杂度提升和并发场景的普及,其设计上的先天缺陷逐渐成为开发中的"重灾区"。
旧版日期时间 API 的痛点早已深入人心:首先是线程安全问题,SimpleDateFormat 和 Calendar 都是可变类,在多线程环境下若未做额外同步处理,极易出现日期解析错乱、计算异常等问题,这也是并发项目中常见的"隐式 Bug";其次是API 设计混乱,Date 类的 getYear() 方法返回值需要加 1900 才能得到实际年份,getMonth() 则以 0 为起始标识月份,这种反直觉的设计让新手频繁踩坑;再者是功能缺失与繁琐,旧 API 未直接支持时区和偏移量的标准化处理,跨时区日期转换需手动计算,日期增减、周期判断等常见操作也需要编写大量冗余代码,不仅效率低下,还容易出错。
为彻底解决这些长期存在的痛点,Java 8 借鉴了 Joda-Time(曾被广泛使用的第三方日期工具库)的优秀设计理念,在 java.time 包下推出了一套全新的日期时间 API。这套新 API 以"不可变对象"为核心设计原则,从根源上保证了线程安全,同时优化了 API 命名与逻辑,让日期时间的创建、解析、计算、时区转换等操作变得直观易懂,还原生支持 ISO 8601 标准(国际通用的日期时间表示格式),完美适配全球化应用的开发需求。
对于开发者而言,掌握 java.time 包的使用已成为必备技能,尤其是在新项目开发或旧系统重构中,新 API 能显著提升日期时间处理的效率与可靠性。本文将聚焦 Java 8 新日期时间体系中的核心类型(如 LocalDate、LocalTime、LocalDateTime、ZonedDateTime 等),逐一拆解其常见 API 的功能与实战用法,并结合具体场景演示代码示例,帮助读者快速上手并灵活运用这套更高效的日期时间处理方案。
LocalDate
java
public static void main(String[] args) {
//首先展示的是localDate的使用方式\
//1。创建指定日期的时间
LocalDate localDate = LocalDate.of(2002, 7, 4);
System.out.println(localDate);
//创建当前的时间
LocalDate localDateNow = LocalDate.now();
System.out.println(localDateNow);
//获取时间的年月日
int year = localDateNow.getYear();
int month = localDateNow.getMonthValue();
int day = localDateNow.getDayOfMonth();
//为时间类型执行输出格式
String format = localDateNow.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
System.out.println(format);
}
LocalTime
java
public static void main(String[] args) {
//输入指定的时间
LocalTime of = LocalTime.of(2, 2, 20,222222);
System.out.println("of = " + of);
//输出当前的时间
LocalTime now = LocalTime.now();
System.out.println("now = " + now);
//获取相应的时间
System.out.println("now.getHour() = " + now.getHour());
System.out.println("now.getMinute() = " + now.getMinute());
System.out.println("now.getSecond() = " + now.getSecond());
System.out.println("now.getNano() = " + now.getNano());
//按着格式输出
String format = now.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
System.out.println(format);
}
LocalDateTime
java
public static void main(String[] args) {
LocalDateTime of = LocalDateTime.of(2002, 7, 26, 5, 35, 9);
System.out.println(of);
LocalDateTime now = LocalDateTime.now();
//按着格式输出时间
String format = now.format(DateTimeFormatter.ISO_DATE_TIME);
System.out.println("format = " + format);
}
日期时间的修改和比较
日期时间的修改
java
private static void testDateModifications() {
//获取时间
LocalDateTime now = LocalDateTime.now();
//将时间的年份修改为1999:修改时间之后,重新返回了一个新的时间,而不是直接进行修改
//源码中也可以看到LocalDateTime,使用final进行修饰,不可以进行修改
LocalDateTime newDateTime = now.withYear(1999);
System.out.println("newDateTime = " + newDateTime);
//修改月份...... 其他的修改操作就忽略了
LocalDateTime newMouthDateTime = now.withMonth(10);
System.out.println("newMouthDateTime = " + newMouthDateTime);
}
针对当前时间进行计算操作
下面,只是展示了对于日期时间的加减操作,对于其他的时间单位,也是相同的。
java
private static void testCalculateDate() {
//创建时间
LocalDateTime now = LocalDateTime.now();
//这个是对于时间+操作(如果传入的是负数的话,就是-操作了)
System.out.println("now.plusDays(1) = " + now.plusDays(1));
//下面是对时间进行-操作(如果传入的是负数的话,就是+操作了)
System.out.println("now.minusDays(3) = " + now.minusDays(3));
}
日期时间的比较
java
private static void testCompareDate() {
//获取当前时间
LocalDate now = LocalDate.now();
//获取指定时间 2022年11月21日
LocalDate localDate = LocalDate.of(2022, 11, 21);
//进行时间比较,返回的是年的插值
int difference= localDate.compareTo(now);
System.out.println("difference = " + difference);
//对比
System.out.println("localDate.isAfter(now) = " + localDate.isAfter(now));
System.out.println("localDate.isEqual(now) = " + localDate.isEqual(now));
System.out.println("localDate.isBefore(now) = " + localDate.isBefore(now));
}
日期的格式化和解析
日期的格式化
java
private static void testFormat() {
//创建时间
LocalDateTime now = LocalDateTime.now();
//自定义时间格式
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//进行格式化操作
String format = now.format(dateTimeFormatter);
//打印格式化后的时间
System.out.println(format);
}
日期的解析
java
private static void testParse() {
LocalDateTime parse = LocalDateTime.parse("1999-12-01 20:11:01",DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(parse);
}
Instant类
待续......