
本文详解为何用 LocalDateTime.parse() 解析 "hh:mm:ss" 格式时间字符串会抛出 DateTimeParseException,并提供基于 LocalTime 和正确 DateTimeFormatter 的可靠排序方案。
本文详解为何用 `localdatetime.parse()` 解析 `"hh:mm:ss"` 格式时间字符串会抛出 `datetimeparseexception`,并提供基于 `localtime` 和正确 `datetimeformatter` 的可靠排序方案。
在 Java 8+ 中处理时间数据时,类型语义必须严格匹配——这是初学者常踩的“类型陷阱”。你遇到的异常:
java.time.format.DateTimeParseException: Text '12:55:36' could not be parsed:
Unable to obtain LocalDateTime from TemporalAccessor: {HourOfAmPm=0, ...}根本原因有两个:
- 类型不匹配:"12:55:36" 仅表示一天中的时刻(时:分:秒),不含日期信息,因此应使用 LocalTime,而非需要年月日+时分秒的 LocalDateTime;
- 格式模式错误:"hh" 表示 12 小时制(取值 01–12),需配合 AM/PM 使用;而你的输入 "20:55:36" 是 24 小时制(20 超出 hh 合法范围),应改用 "HH"(00–23)。
✅ 正确做法如下:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); // 注意:HH,非 hh
List<PostX> posts1 = posts.stream()
.sorted(Comparator.comparing(post -> LocalTime.parse(post.timePublication, formatter)))
.limit(5)
.toList();为便于验证结果,建议在 PostX 类中重写 toString() 方法(非必需但强烈推荐):
立即学习“Java免费学习笔记(深入)”;
@Override
public String toString() {
return String.format("PostX [id=%d, name=%s, score=%d, timePublication=%s]",
id, name, score, timePublication);
}完整可运行示例(含修复后输出):
// ...(PostX 类定义 + toString())
public static void main(String[] args) {
List<PostX> posts = List.of(
new PostX(1,"post1", 10, "20:55:36"),
new PostX(2,"post2", 0, "12:55:36"),
new PostX(3,"post3", 100, "19:55:36"),
new PostX(4,"post4", 1000, "23:55:36"),
new PostX(5,"post5", 10, "01:50:36"),
new PostX(6,"post6", 3, "20:55:36"),
new PostX(7,"post7", 4, "20:15:36")
);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
List<PostX> top5 = posts.stream()
.sorted(Comparator.comparing(p -> LocalTime.parse(p.timePublication, formatter)))
.limit(5)
.toList();
top5.forEach(System.out::println);
}输出(按时间升序排列):
PostX [id=5, name=post5, score=10, timePublication=01:50:36] PostX [id=2, name=post2, score=0, timePublication=12:55:36] PostX [id=3, name=post3, score=100, timePublication=19:55:36] PostX [id=7, name=post7, score=4, timePublication=20:15:36] PostX [id=1, name=post1, score=10, timePublication=20:55:36]
? 关键注意事项:
- 若原始数据含日期(如 "2024-05-20 14:30:00"),才考虑 LocalDateTime + "yyyy-MM-dd HH:mm:ss";
- LocalTime 是不可变、线程安全的,适合纯时间场景;
- DateTimeFormatter 是线程安全的,可复用(建议声明为 static final);
- 避免在 Comparator.comparing() 中重复解析——若需多次排序或过滤,可预先将 timePublication 解析为 LocalTime 字段并缓存。
掌握 Temporal 类型与格式器的精确对应关系,是写出健壮时间处理代码的第一步。


















