Java 8 java.time日期时间API完整使用指南与代码实例
本文详细介绍了Java 8引入的java.time日期时间API,通过大量实用代码示例展示了LocalDate、LocalTime、LocalDateTime、ZonedDateTime等核心类的使用方法,包括日期创建、运算比较、时区转换、格式化解析等关键操作。内容涵盖Period和Duration时间段计算、DateTimeFormatter格式化处理以及Instant时间戳应用,并提供完整的综合示例,帮助开发者从旧版Date/Calendar平滑过渡到新版API,提升日期时间处理效率和代码质量。
java.time 是 Java 8 引入的日期和时间 API,它解决了旧的 java.util.Date 和 java.util.Calendar 类的诸多问题,提供了更直观、线程安全且功能丰富的日期时间处理能力。
主要特点
1、不可变性:所有核心类都是不可变的,线程安全
2、清晰的API设计:方法命名直观,易于理解
3、时区支持:完善的时区处理
4、格式化解析:强大的格式化功能
核心类概览
1. LocalDate - 日期(不含时间)
import java.time.LocalDate;
import java.time.DayOfWeek;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
// 创建日期
LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2024, 5, 15);
LocalDate parsedDate = LocalDate.parse("2024-05-20");
System.out.println("今天: " + today);
System.out.println("特定日期: " + specificDate);
System.out.println("解析日期: " + parsedDate);
// 日期运算
LocalDate tomorrow = today.plusDays(1);
LocalDate nextWeek = today.plusWeeks(1);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("明天: " + tomorrow);
System.out.println("下周: " + nextWeek);
System.out.println("上月: " + lastMonth);
// 日期比较
boolean isAfter = tomorrow.isAfter(today);
boolean isBefore = lastMonth.isBefore(today);
boolean isEqual = today.equals(LocalDate.now());
System.out.println("明天在今天之后: " + isAfter);
System.out.println("上月在今天之前: " + isBefore);
// 获取日期信息
DayOfWeek dayOfWeek = today.getDayOfWeek();
int dayOfMonth = today.getDayOfMonth();
int dayOfYear = today.getDayOfYear();
System.out.println("星期: " + dayOfWeek);
System.out.println("月中第几天: " + dayOfMonth);
System.out.println("年中第几天: " + dayOfYear);
// 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formatted = today.format(formatter);
System.out.println("格式化日期: " + formatted);2. LocalTime - 时间(不含日期)
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
// 创建时间
LocalTime now = LocalTime.now();
LocalTime specificTime = LocalTime.of(14, 30, 15); // 14:30:15
LocalTime parsedTime = LocalTime.parse("09:45:00");
System.out.println("现在时间: " + now);
System.out.println("特定时间: " + specificTime);
System.out.println("解析时间: " + parsedTime);
// 时间运算
LocalTime inOneHour = now.plusHours(1);
LocalTime in30Minutes = now.plusMinutes(30);
LocalTime minus15Seconds = now.minusSeconds(15);
System.out.println("一小时后: " + inOneHour);
System.out.println("30分钟后: " + in30Minutes);
// 格式化时间
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH时mm分ss秒");
String formattedTime = now.format(timeFormatter);
System.out.println("格式化时间: " + formattedTime);3. LocalDateTime - 日期时间
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
// 创建日期时间
LocalDateTime now = LocalDateTime.now();
LocalDateTime specificDateTime = LocalDateTime.of(2024, 5, 15, 14, 30, 0);
System.out.println("现在: " + now);
System.out.println("特定日期时间: " + specificDateTime);
// 组合日期和时间
LocalDate date = LocalDate.of(2024, 5, 15);
LocalTime time = LocalTime.of(14, 30);
LocalDateTime combined = LocalDateTime.of(date, time);
System.out.println("组合日期时间: " + combined);
// 格式化
DateTimeFormatter dtFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = now.format(dtFormatter);
System.out.println("格式化日期时间: " + formatted);4. ZonedDateTime - 带时区的日期时间
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
// 创建带时区的日期时间
ZonedDateTime nowInShanghai = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime nowInNewYork = ZonedDateTime.now(ZoneId.of("America/New_York"));
System.out.println("上海时间: " + nowInShanghai);
System.out.println("纽约时间: " + nowInNewYork);
// 时区转换
ZonedDateTime tokyoTime = nowInShanghai.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println("对应的东京时间: " + tokyoTime);
// 获取所有可用时区
System.out.println("\n部分可用时区:");
ZoneId.getAvailableZoneIds().stream()
.filter(zone -> zone.contains("Asia"))
.limit(5)
.forEach(System.out::println);5. Period 和 Duration - 时间段
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Period;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
// Period - 基于日期的时段(年、月、日)
LocalDate startDate = LocalDate.of(2020, 1, 1);
LocalDate endDate = LocalDate.of(2024, 5, 15);
Period period = Period.between(startDate, endDate);
System.out.println("时间段: " + period.getYears() + "年 " +
period.getMonths() + "月 " +
period.getDays() + "天");
// Duration - 基于时间的时段(小时、分钟、秒)
LocalTime startTime = LocalTime.of(9, 0);
LocalTime endTime = LocalTime.of(17, 30);
Duration duration = Duration.between(startTime, endTime);
System.out.println("工作时间: " + duration.toHours() + "小时 " +
(duration.toMinutes() % 60) + "分钟");
// 使用 ChronoUnit 计算
long daysBetween = ChronoUnit.DAYS.between(startDate, endDate);
long hoursBetween = ChronoUnit.HOURS.between(startTime, endTime);
System.out.println("总天数: " + daysBetween);
System.out.println("总小时数: " + hoursBetween);6. DateTimeFormatter - 格式化
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
LocalDateTime now = LocalDateTime.now();
// 预定义的格式化器
System.out.println("ISO格式: " + now.format(DateTimeFormatter.ISO_DATE_TIME));
System.out.println("基本ISO格式: " + now.format(DateTimeFormatter.BASIC_ISO_DATE));
// 自定义格式化器
DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒");
System.out.println("中文格式: " + now.format(customFormatter));
// 本地化格式化
DateTimeFormatter germanFormatter = DateTimeFormatter.ofPattern("dd. MMMM yyyy", Locale.GERMAN);
System.out.println("德语格式: " + now.format(germanFormatter));
// 解析字符串为日期时间
String dateString = "2024-05-15 14:30:00";
DateTimeFormatter parser = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime parsedDateTime = LocalDateTime.parse(dateString, parser);
System.out.println("解析结果: " + parsedDateTime);7. Instant - 时间戳
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
// 获取当前时间戳
Instant now = Instant.now();
System.out.println("当前时间戳: " + now);
// 时间戳运算
Instant inOneHour = now.plusSeconds(3600);
System.out.println("一小时后: " + inOneHour);
// 与 LocalDateTime 转换
LocalDateTime localDateTime = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
Instant backToInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
System.out.println("转换为LocalDateTime: " + localDateTime);
System.out.println("转换回Instant: " + backToInstant);完整示例
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
public class DateTimeExample {
public static void main(String[] args) {
// 1. 生日计算
LocalDate birthday = LocalDate.of(1990, 8, 15);
LocalDate today = LocalDate.now();
Period age = Period.between(birthday, today);
System.out.printf("年龄: %d岁%d个月%d天%n",
age.getYears(), age.getMonths(), age.getDays());
// 2. 会议安排
LocalDateTime meetingStart = LocalDateTime.of(2024, 5, 20, 14, 0);
Duration meetingDuration = Duration.ofHours(2).plusMinutes(30);
LocalDateTime meetingEnd = meetingStart.plus(meetingDuration);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM月dd日 HH:mm");
System.out.printf("会议时间: %s - %s%n",
meetingStart.format(formatter), meetingEnd.format(formatter));
// 3. 国际会议时区转换
ZonedDateTime nyMeeting = ZonedDateTime.of(
LocalDateTime.of(2024, 5, 20, 9, 0),
ZoneId.of("America/New_York")
);
ZonedDateTime shMeeting = nyMeeting.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
System.out.printf("纽约时间: %s%n", nyMeeting);
System.out.printf("上海时间: %s%n", shMeeting);
// 4. 日期比较
LocalDate deadline = LocalDate.of(2024, 6, 1);
long daysUntilDeadline = ChronoUnit.DAYS.between(today, deadline);
System.out.printf("距离截止日期还有 %d 天%n", daysUntilDeadline);
}
}总结
java.time 包提供了:
1、清晰的类型分离:日期、时间、日期时间、时区等都有专门的类
2、不可变性和线程安全
3、流畅的API:方法链式调用
4、强大的时区支持
5、丰富的格式化选项
这些特性使得日期时间处理变得更加简单、安全和直观。
最后更新于3月前
本文由人工编写,AI优化,转载请注明原文地址: Java 8时间日期处理:java.time使用详解与实战代码示例
推荐阅读
评论 (3)
发表评论
昵称:加载中...
马小玲2025-12-04 12:06:46
文章讲得很清楚,示例代码也很实用!终于搞懂了LocalDate的用法,比老Date类好用太多了。感谢作者分享!
温柔一刀2025-11-12 19:47:29
感谢分享!java.time确实比Date好用太多了,代码示例很实用,特别是日期比较和格式化部分。请问在跨时区业务场景中,ZonedDateTime和Instant该如何选择?
晨曦微露2025-11-10 18:23:19
之前一直用老Date类各种坑,这个java.time教程太及时了!正好用LocalDate重构了项目的报表模块,代码清爽多了,再也不用担心线程安全问题了。