LocalDateTime 是 Java 8 引入的日期时间 API 中的核心类之一,位于 java.time 包下,用于表示不带时区信息的日期和时间(格式为 yyyy-MM-ddTHH:mm:ss.SSS)。它是不可变类,线程安全,解决了旧版 Date 和 Calendar 类的线程安全问题和设计缺陷。
LocalDateTime 主要特点:
不可变性:所有修改操作(如 plusXxx()、minusXxx()、withXxx())都会返回新的 LocalDateTime 对象,原对象保持不变。
丰富的 API:提供了直接获取 / 修改年、月、日、时、分、秒等字段的方法。
格式化支持:配合 DateTimeFormatter 可灵活转换为字符串(如中文格式、自定义格式)。
无时区依赖:如果需要处理时区,可结合 ZonedDateTime 或 ZoneId 使用。
以下是 LocalDateTime 的常用操作示例:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class LocalDateTimeExamples { public static void main(String[] args) { // 1. 创建LocalDateTime对象 // 方式1:指定具体日期时间 LocalDateTime dt1 = LocalDateTime.of(2023, 10, 5, 15, 30, 45); // 方式2:获取当前日期时间 LocalDateTime now = LocalDateTime.now(); // 2. 获取日期时间的各个字段 System.out.println("年份: " + dt1.getYear()); // 2023 System.out.println("月份: " + dt1.getMonthValue()); // 10(1-12) System.out.println("日: " + dt1.getDayOfMonth()); // 5 System.out.println("小时: " + dt1.getHour()); // 15(24小时制) System.out.println("分钟: " + dt1.getMinute()); // 30 System.out.println("秒: " + dt1.getSecond()); // 45 // 3. 修改日期时间(返回新对象,原对象不变) LocalDateTime modified1 = dt1.plusYears(1).minusMonths(3); // 加1年,减3个月 LocalDateTime modified2 = dt1.withDayOfMonth(10).withHour(20); // 改日为10,小时为20 System.out.println("修改后1: " + modified1); // 2024-07-05T15:30:45 System.out.println("修改后2: " + modified2); // 2023-10-10T20:30:45 // 4. 日期时间比较 System.out.println("dt1在now之前?" + dt1.isBefore(now)); // 根据实际时间判断 System.out.println("dt1在now之后?" + dt1.isAfter(now)); // 根据实际时间判断 // 5. 格式化日期时间 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); String formatted = dt1.format(formatter); System.out.println("格式化后: " + formatted); // 2023年10月05日 15:30:45 } }
运行结果:
年份: 2023 月份: 10 日: 5 小时: 15 分钟: 30 秒: 45 修改后1: 2024-07-05T15:30:45 修改后2: 2023-10-10T20:30:45 dt1在now之前?true dt1在now之后?false 格式化后: 2023年10月05日 15:30:45
用于创建 LocalDateTime 的实例。
方法 | 用途 |
now() | 获取当前日期时间,使用系统默认时区。 |
of(年,月,日,时,分,秒) | 手动指定日期时间创建实例,参数需符合逻辑(如月份 1-12,日期不超过当月最大天数)。 |
parse(CharSequence) | 解析字符串为 LocalDateTime,字符串需符合默认格式 yyyy-MM-ddTHH:mm:ss |
示例:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class LocalDateTimeDemo { public static void main(String[] args) { // 1. 获取当前日期时间 LocalDateTime now = LocalDateTime.now(); System.out.println("当前时间: " + now); // 例如:2023-10-05T15:30:45.123 // 2. 手动创建(2023年12月25日 18:30:00) LocalDateTime christmas = LocalDateTime.of(2023, 12, 25, 18, 30, 0); System.out.println("圣诞节: " + christmas); // 2023-12-25T18:30 // 3. 解析字符串(默认格式) LocalDateTime parsed = LocalDateTime.parse("2023-01-01T00:00:00"); System.out.println("解析结果: " + parsed); // 2023-01-01T00:00 // 4. 解析自定义格式(需指定DateTimeFormatter) DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); LocalDateTime customParsed = LocalDateTime.parse("2023/10/05 16:45:30", formatter); System.out.println("自定义解析: " + customParsed); // 2023-10-05T16:45:30 } }
运行结果:
当前时间: 2025-09-04T22:26:20.302435500 圣诞节: 2023-12-25T18:30 解析结果: 2023-01-01T00:00 自定义解析: 2023-10-05T16:45:30
用户获取 LocalDateTime 实例中某个字段的值,如年份。下面假设 LocalDateTime 表示的日期时间为“2023 年 10 月 5 日 15 时 30 分 45 秒”。
方法 | 用途 |
getYear() | 获取年份。例如:now.getYear() → 2023 |
getMonthValue() | 获取月份(1-12)。例如:now.getMonthValue() → 10 |
getDayOfMonth() | 获取日(1-31)。例如:now.getDayOfMonth() → 5 |
getHour() | 获取小时(0-23)。例如:now.getHour() → 15 |
getMinute() | 获取分钟(0-59)。例如:now.getMinute() → 30 |
getSecond() | 获取秒(0-59)。例如:now.getSecond() → 45 |
示例:
import java.time.LocalDateTime; public class LocalDateTimeFields { public static void main(String[] args) { // 创建一个指定的日期时间对象 LocalDateTime dt = LocalDateTime.of(2023, 10, 5, 15, 30, 45); // 获取并打印各个字段的值 System.out.println("年份: " + dt.getYear()); // 2023 System.out.println("月份: " + dt.getMonthValue()); // 10 System.out.println("小时: " + dt.getHour()); // 15 } }
运行结果:
年份: 2023 月份: 10 小时: 15
LocalDateTime 是不可变类,所有修改方法都会返回新实例,原实例不变。
方法 | 用途 |
plusYears(long) | 增加年份。例如: dt.plusYears(1) → 年份 + 1 |
minusMonths(long) | 减少月份。例如: dt.minusMonths(2) → 月份 - 2 |
withDayOfMonth(int) | 修改日。例如: dt.withDayOfMonth(1) → 改为当月 1 日 |
withHour(int) | 修改小时。例如: dt.withHour(0) → 改为 0 点 |
示例:
import java.time.LocalDateTime; public class LocalDateTimeModification { public static void main(String[] args) { // 创建初始日期时间对象 LocalDateTime dt = LocalDateTime.of(2023, 10, 5, 15, 30, 45); // 增加1年,减少3个月 LocalDateTime modified = dt.plusYears(1).minusMonths(3); System.out.println(modified); // 2024-07-05T15:30:45 // 修改为当月10日,小时改为20点 LocalDateTime adjusted = dt.withDayOfMonth(10).withHour(20); System.out.println(adjusted); // 2023-10-10T20:30:45 } }
运行结果:
2024-07-05T15:30:45 2023-10-10T20:30:45
使用 format(DateTimeFormatter) 方法将 LocalDateTime 转换为指定格式的字符串。
示例:
import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class DateTimeFormatterExample { public static void main(String[] args) { // 获取当前日期时间 LocalDateTime dt = LocalDateTime.now(); // 创建格式化器,指定输出格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss"); // 格式化日期时间 String formatted = dt.format(formatter); // 输出格式化后的结果 System.out.println(formatted); // 例如:2023年10月05日 15:30:45 } }
运行结果:
2025年09月04日 22:28:23
方法 | 用途 |
isBefore(LocalDateTime) | 判断当前时间是否在参数之前。例如: dt1.isBefore(dt2) → true/false 如果 dt1 在 dt2 之前,则返回 true。 如果 dt1 在 dt2 之后或相等,则返回 false。 |
isAfter(LocalDateTime) | 判断当前时间是否在参数之后。例如: dt1.isAfter(dt2) → true/false 如果 dt1 在 dt2 之后,则返回 true。 如果 dt1 在 dt2 之前或相等,则返回 false。 |
isEqual(LocalDateTime) | 判断两个时间是否相等。例如: dt1.isEqual(dt2) → true/false 如果 dt1 和 dt2 相等,则返回 true。 如果 dt1 和 dt2 不相等,则返回 false。 |
示例:
import java.time.LocalDateTime; public class LocalDateTimeComparison { public static void main(String[] args) { // 创建两个LocalDateTime对象 LocalDateTime dt1 = LocalDateTime.of(2023, 10, 5, 10, 0); LocalDateTime dt2 = LocalDateTime.of(2023, 10, 5, 15, 0); // 比较两个日期时间 System.out.println(dt1.isBefore(dt2)); // true System.out.println(dt1.isAfter(dt2)); // false } }
(1)无时区信息:LocalDateTime 不包含时区,若需处理时区,需结合 ZonedDateTime 或 ZoneId 使用。
// 转换为带时区的时间 LocalDateTime local = LocalDateTime.now(); ZonedDateTime zoned = local.atZone(ZoneId.of("Asia/Shanghai"));
(2)参数合法性:of(...) 方法的参数需符合逻辑(如月份不能为 0 或 13,日期不能超过当月最大天数),否则会抛 DateTimeException。
(3)不可变性:所有修改方法(plusXxx、minusXxx、withXxx)均返回新实例,原实例不会被修改。
(4)默认解析格式:parse(String) 方法默认解析 yyyy-MM-ddTHH:mm:ss 格式,其他格式需显式指定 DateTimeFormatter。
LocalDateTime 是处理本地日期时间的最佳选择,相比旧 API 具有以下优势:
不可变设计,线程安全;
方法命名清晰,易于理解和使用;
支持链式调用,代码简洁;
内置格式化和解析功能,无需依赖 SimpleDateFormat(线程不安全)。
在实际开发中,建议优先使用 LocalDateTime 及其相关类(LocalDate、LocalTime、ZonedDateTime 等)处理日期时间逻辑。