system.currenttimemillis()返回自1970年1月1日utc起的毫秒数,无格式与时区信息;需用simpledateformat(java 8前,非线程安全)或datetimeformatter+instant(java 8+,推荐,线程安全)进行格式化,并注意时区选择与实例复用。

System.currentTimeMillis() 返回的是从 1970 年 1 月 1 日 00:00:00 UTC(即 Unix 纪元)到当前时刻的毫秒数,它本身只是一个 long 类型的时间戳,**不带格式、不带时区信息,也不能直接格式化**。要把它变成可读的日期时间字符串(比如 "2024-05-20 14:30:45"),必须借助日期时间格式化工具。
用 SimpleDateFormat 格式化(适用于 Java 8 以前)
这是老式但仍在部分项目中使用的做法。需注意:SimpleDateFormat 不是线程安全的,多线程下要避免共享实例。
- 先用
new Date(System.currentTimeMillis())把毫秒值转成Date对象 - 再用
SimpleDateFormat指定模式(如"yyyy-MM-dd HH:mm:ss")进行格式化
long ts = System.currentTimeMillis();<br>
Date date = new Date(ts);<br>
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");<br>
String formatted = sdf.format(date); // 如:"2024-05-20 14:30:45"
用 DateTimeFormatter + Instant(推荐,Java 8+)
这是现代、线程安全、更清晰的方式。核心思路是:毫秒 → Instant → 转为本地时区的 ZonedDateTime 或 LocalDateTime → 格式化。
-
Instant.ofEpochMilli(ts)将毫秒转为 UTC 时间点 - 用
atZone(ZoneId.systemDefault())转成本地时区的ZonedDateTime - 用预定义或自定义的
DateTimeFormatter格式化
long ts = System.currentTimeMillis();<br>
Instant instant = Instant.ofEpochMilli(ts);<br>
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());<br>
String formatted = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(zdt);
快速获取常用格式(Java 8+ 一行写法)
如果只是临时调试或简单输出,可以链式调用简化:
- 本地时间(默认时区):
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")<br> .format(Instant.now().atZone(ZoneId.systemDefault())) - UTC 时间:
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneOffset.UTC)<br> .format(Instant.now())
注意事项
- 不要直接对
System.currentTimeMillis()做字符串拼接或数学运算来“模拟”格式化——不可靠且易出错 - 时区很重要:同一毫秒值,在北京和纽约显示的“年月日时分秒”不同,务必明确你要的是哪个时区的时间
- 避免在循环或高并发场景中反复创建
SimpleDateFormat实例;若必须用,建议用ThreadLocal包装或改用DateTimeFormatter(它是不可变且线程安全的)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











