Java LocalTime案例:如何获取当前时间与自定义时间值
目录导读
- LocalTime 简介:什么是 LocalTime,与 Date/Calendar 的区别
- 获取当前时间:now() 方法详解与代码示例
- 获取指定时间:of() 方法与字符串解析
- 时间格式化与显示:DateTimeFormatter 最佳实践
- 时间运算与比较:加减、相差、是否早于/晚于
- 常见问答:面试高频问题与开发避坑指南
本文源码均基于 Java 8+,兼容 Java 11/17/21,全文约 1350 字,深度覆盖搜索引擎收录要点。
LocalTime 简介:为什么它比 Date 更好用?
Java 8 引入了全新的 java.time 包,LocalTime 代表一天中的某个时刻(如 14:30:15.123456789),不包含日期和时区,相比老旧的 java.util.Date 和 Calendar,LocalTime 具有:
- 线程安全:不可变对象,无需同步
- API 清晰:没有时区干扰,纯时间操作
- 精度可达纳秒:支持
HH:mm:ss.nnnnnnnnn
案例前提:假设你正在开发一个会议预约系统,需要记录每个时段的开始时间(如 09:30:00),这时 LocalTime 就是最合适的选择。
获取当前时间:now() 方法
1 基本用法
import java.time.LocalTime;
public class CurrentTimeDemo {
public static void main(String[] args) {
// 获取当前系统时间(精确到毫秒)
LocalTime currentTime = LocalTime.now();
System.out.println("当前时间: " + currentTime);
// 输出示例: 14:35:20.123456
}
}
关键点:
now()默认使用系统默认时区,但 LocalTime 本身不带时区信息- 多次调用
now()会得到不同的值,适合实时场景
2 获取更精细的精度
// 获取只包含时、分、秒的时间(丢弃纳秒) LocalTime truncated = LocalTime.now().withNano(0); System.out.println(truncated); // 14:35:20 // 获取只包含时、分的时间 LocalTime hourMinute = LocalTime.now().withSecond(0).withNano(0); System.out.println(hourMinute); // 14:35
3 实际开发案例:前端传入时间戳转为 LocalTime
// 假设从前端收到毫秒级时间戳,需要提取时间部分
long timestamp = System.currentTimeMillis();
LocalTime timeFromTs = LocalTime.ofInstant(
java.time.Instant.ofEpochMilli(timestamp),
java.time.ZoneId.systemDefault()
);
System.out.println("时间戳对应时间: " + timeFromTs);
获取指定时间:of() 方法与字符串解析
1 使用 of() 构造任意时间
// 重载方法:of(hour, minute), of(hour, minute, second), of(hour, minute, second, nanoOfSecond) LocalTime startTime = LocalTime.of(9, 30); // 09:30 LocalTime endTime = LocalTime.of(18, 0, 0); // 18:00 LocalTime precise = LocalTime.of(12, 0, 0, 500_000_000); // 12:00:00.500
验证:如果小时数 >23 或分钟数 >59,会抛出 DateTimeException。
2 从字符串解析(最常见的企业场景)
import java.time.format.DateTimeFormatter;
// 解析 "HH:mm" 格式
LocalTime fromString1 = LocalTime.parse("10:15");
System.out.println(fromString1); // 10:15
// 解析 "HH:mm:ss" 格式
LocalTime fromString2 = LocalTime.parse("22:45:30");
System.out.println(fromString2); // 22:45:30
// 解析自定义格式:注意使用 DateTimeFormatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
LocalTime custom = LocalTime.parse("14:30:00.123", formatter);
System.out.println(custom); // 14:30:00.123
常见错误示例:直接 parse("10:15:30.123") 会报错,因为默认格式是 HH:mm:ss.nnnnnnnnn。解决办法:必须明确指定 DateTimeFormatter。
时间格式化与显示:让时间更美观
1 内置格式器
LocalTime time = LocalTime.of(15, 8, 45);
System.out.println(time.format(DateTimeFormatter.ISO_LOCAL_TIME));
// 输出: 15:08:45
System.out.println(time.format(DateTimeFormatter.ofPattern("HH:mm")));
// 输出: 15:08
2 格式化技巧:上午/下午显示
DateTimeFormatter amPm = DateTimeFormatter.ofPattern("hh:mm a");
System.out.println(LocalTime.of(8, 0).format(amPm)); // 08:00 AM
System.out.println(LocalTime.of(20, 0).format(amPm)); // 08:00 PM
3 国际化场景:地区时间格式
import java.time.format.FormatStyle;
import java.util.Locale;
DateTimeFormatter german = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
.withLocale(Locale.GERMAN);
System.out.println(LocalTime.NOON.format(german)); // 12:00
时间运算与比较:灵活处理业务逻辑
1 加减时间
LocalTime now = LocalTime.now(); LocalTime later = now.plusHours(2); // 加2小时 LocalTime earlier = now.minusMinutes(30); // 减30分钟 LocalTime withSeconds = now.withSecond(59); // 将秒设为59
注意:加减后如果跨天(如 23:30 + 1小时 = 00:30),LocalTime 会自动回绕到第二天,不会进位到日期,如果你需要跨天感知,请使用 LocalDateTime。
2 比较大小:isBefore / isAfter
LocalTime opening = LocalTime.of(9, 0);
LocalTime closing = LocalTime.of(17, 0);
LocalTime current = LocalTime.now();
if (current.isBefore(closing) && current.isAfter(opening)) {
System.out.println("店铺营业中");
}
3 获取两个时间相差的秒数/分钟数
LocalTime start = LocalTime.of(8, 0);
LocalTime end = LocalTime.of(17, 30);
long minutesBetween = java.time.Duration.between(start, end).toMinutes();
System.out.println("相差 " + minutesBetween + " 分钟"); // 570分钟
// 如果结束时间在开始之前,会返回负值
LocalTime earlierTime = LocalTime.of(20, 0);
LocalTime laterTime = LocalTime.of(6, 0); // 次日
long diff = java.time.Duration.between(earlierTime, laterTime).toHours();
System.out.println(diff); // 负值,需要特殊处理跨天场景
常见问答(FAQ)
Q1:LocalTime 和 LocalDateTime 有什么区别?
A:LocalTime 只存储时间部分(时:分:秒:纳秒),不包含日期;LocalDateTime 包含日期+时间,你需要哪个?
- 会议固定每天同一时间 → 用 LocalTime
- 具体的2024年3月15日14:00 → 用 LocalDateTime
Q2:如何将数据库的 TIME 类型映射为 LocalTime?
A:使用 JPA/Hibernate 时,字段类型声明为:
@Column(name = "start_time", columnDefinition = "TIME") private LocalTime startTime;
Spring Boot 默认支持该映射,无需额外转换。
Q3:如何获取当前时间的 0 时 0 分 0 秒(午夜)?
A:直接用 LocalTime.MIDNIGHT 常量,或者:
LocalTime midnight = LocalTime.of(0, 0, 0); // 或 LocalTime midnight2 = LocalTime.now().with(LocalTime.MIDNIGHT);
Q4:为什么我的 parse 总抛出异常?
A:最常见原因是字符串格式与默认格式不匹配,默认格式是 HH:mm:ss.nnnnnnnnn,如果你的字符串是 HH:mm 或包含日期,必须使用自定义 DateTimeFormatter。
Q5:LocalTime 如何跨时区处理?
A:LocalTime 本身不跨时区,如果你需要转换时区,应该使用 ZonedDateTime 或 OffsetTime。
ZonedDateTime nowNy = ZonedDateTime.now(ZoneId.of("America/New_York"));
LocalTime timeNy = nowNy.toLocalTime();
LocalTime 的最佳使用场景
| 场景 | 推荐方案 |
|---|---|
| 获取当前时间并显示 | LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss")) |
| 数据库存储时间字段 | JPA 自动映射 LocalTime |
| 时间区间判断(如9:00-17:00) | isBefore() / isAfter() 组合 |
| 字符串转时间(如Excel导入) | LocalTime.parse(str, DateTimeFormatter) |
| 时间差计算(工时统计) | Duration.between() |
最后一道防线:使用前请确认你的 Java 版本 >= 8,且在 pom.xml 或 build.gradle 中无需额外依赖,如果你正在迁移旧项目,建议将所有的 Date 时间操作逐步替换为 LocalTime,以获得更好的可读性和线程安全性。
本文已收录于 Java 时间处理系列,更多内容请关注作者后续更新。
