Java中format(long millis)方法推荐用LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault())配合DateTimeFormatter格式化,线程安全且语义清晰,支持多种预定义格式如"yyyy-MM-dd HH:mm:ss"。

Java 中 System.currentTimeMillis() 返回的是自 1970-01-01 00:00:00 UTC 起的毫秒数,是 long 类型,不能直接当时间字符串用。要格式化成可读日期(比如 "2024-05-20 14:30:45"),需借助 java.time 或旧版 SimpleDateFormat ——但推荐前者,线程安全、语义清晰、不易出错。
使用 LocalDateTime + DateTimeFormatter(推荐)
这是现代 Java(8+)的标准做法,避免了 SimpleDateFormat 的线程安全问题和时区歧义。
- 先将毫秒转为
Instant,再结合系统默认时区转成LocalDateTime - 用预定义或自定义的
DateTimeFormatter格式化 - 示例代码:
return LocalDateTime.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault())
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
支持常用格式的工具方法
实际项目中常需多种输出格式,可封装成静态工具类,提供常用快捷方法:
-
toDateTime(millis)→ "2024-05-20 14:30:45" -
toDate(millis)→ "2024-05-20" -
toTime(millis)→ "14:30:45" -
toFullIso(millis)→ "2024-05-20T14:30:45.123"
每个方法内部复用 DateTimeFormatter 静态实例,避免重复创建对象,提升性能。
注意时区与精度问题
毫秒值本身无时区信息,格式化结果依赖你选择的时区:
- 用
ZoneId.systemDefault()表示本地时区(最常用) - 若需固定时区(如 UTC),改用
ZoneOffset.UTC - 毫秒级精度已足够日常使用;如需纳秒,原始毫秒无法提供,需额外记录纳秒部分
避免踩坑:别用 SimpleDateFormat 做静态成员
虽然还能用,但 SimpleDateFormat 不是线程安全的。如果非要用(如兼容 JDK 7),务必做到:
- 每次调用都新建实例(简单但稍慢)
- 或用
ThreadLocal<SimpleDateFormat>包装(稍复杂但高效) - 切忌声明为
static final字段直接共享 —— 多线程下极易格式错乱

















