system.currenttimemillis() 返回自1970年1月1日utc起的毫秒数,需配合date或java.time api格式化为字符串;推荐java 8+用instant、zoneddatetime和datetimeformatter,避免simpledateformat线程安全问题及老api缺陷。

System.currentTimeMillis() 返回的是从1970年1月1日00:00:00 UTC开始的毫秒数,它本身不是日期字符串,也不能直接“格式化”——必须配合 java.util.Date 或(更推荐)java.time API 才能转成可读的时间格式。
用 SimpleDateFormat 格式化(适用于 Java 8 以前)
这是最常见也最容易上手的方式,但要注意线程安全问题(SimpleDateFormat 非线程安全):
- 先用
new Date(System.currentTimeMillis())构造一个 Date 对象 - 创建
SimpleDateFormat实例,指定模式如"yyyy-MM-dd HH:mm:ss" - 调用
format()方法得到字符串
示例代码:
long now = System.currentTimeMillis();
Date date = new Date(now);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String formatted = sdf.format(date); // 如:2024-05-20 14:30:45
用 LocalDateTime + Instant(Java 8+ 推荐方式)
现代写法更清晰、不可变、线程安全:
- 通过
Instant.ofEpochMilli(System.currentTimeMillis())获取瞬时时间 - 转为带时区的
ZonedDateTime(例如使用系统默认时区:ZoneId.systemDefault()) - 再提取
LocalDateTime,或直接用DateTimeFormatter格式化
示例代码:
long now = System.currentTimeMillis();
Instant instant = Instant.ofEpochMilli(now);
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = zdt.format(formatter); // 同样输出:2024-05-20 14:30:45
常见格式模式说明
无论用哪种方式,格式字符串含义一致:
-
yyyy:4位年份(如 2024) -
MM:两位月份(01–12) -
dd:两位日期(01–31) -
HH:24小时制小时(00–23) -
mm:分钟(00–59) -
ss:秒(00–59) -
SSS:毫秒(000–999),可用于显示精确到毫秒的时间
避免踩坑的关键点
实战中容易忽略但影响结果的细节:
- 不要把
System.currentTimeMillis()当作时间对象直接 toString() —— 它只是 long 值,比如1716215445123 - SimpleDateFormat 不要复用在多线程环境,建议每次新建或使用 ThreadLocal 封装
- Java 8+ 强烈建议用
java.time,避免老 API 的设计缺陷(如月份从 0 开始) - 跨时区场景下,务必明确指定
ZoneId,否则可能因服务器时区和用户预期不一致导致显示错误
不复杂但容易忽略,关键是分清“毫秒值”和“时间表示”的区别,选对转换路径就行。











