System.currentTimeMillis() 返回的毫秒数本身就是基于 GMT/UTC 的时间戳,无需转换;它遵循 Unix 时间标准,不受本地时区影响,是纯数值且无时区信息。

System.currentTimeMillis() 返回的是自 1970年1月1日 00:00:00 GMT(UTC) 起经过的毫秒数,它本身就是一个 GMT/UTC 时间戳,**不需要“转换”为 GMT 时间**——它本来就是基于 GMT 的。
为什么说它已经是 GMT 时间?
Java 的 System.currentTimeMillis() 遵循 Unix 时间标准:
- 始终以 GMT(等价于 UTC,忽略闰秒)为基准;
- 不受本地时区、系统设置或夏令时影响;
- 返回值是纯数值(long 类型),不携带时区信息。
常见误解:把它当成“本地时间”再转 GMT
错误做法示例(无需这样做):
// ❌ 错误:把毫秒数当成本地时间再“转成”GMT(逻辑颠倒)
long localMs = System.currentTimeMillis();
Date date = new Date(localMs); // Date 内部仍是 GMT 毫秒,只是 toString() 显示本地时区
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String gmtStr = sdf.format(date); // 这步看似转 GMT,实则绕弯且易出错
正确使用方式:直接用毫秒值表示 GMT 时间
若需获取 GMT 时间的可读字符串,应:
- 创建
SimpleDateFormat或DateTimeFormatter,并显式设时区为GMT或UTC; - 用
System.currentTimeMillis()构造Date或Instant; - 格式化时确保时区设置正确。
✅ 推荐(Java 8+):
Instant now = Instant.now(); // 等价于 Instant.ofEpochMilli(System.currentTimeMillis()) String gmtStr = now.toString(); // 默认输出 ISO-8601 格式,带 'Z'(即 UTC) // 示例:2024-05-20T14:23:45.123Z
✅ 兼容旧版(Java 7 及以前):
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
sdf.setTimeZone(TimeZone.getTimeZone("GMT")); // 关键:设为 GMT 时区
String gmtStr = sdf.format(new Date(System.currentTimeMillis()));
// 示例:2024-05-20 14:23:45.123
注意时区缩写与 ID 的区别
避免使用 "GMT"、"UTC" 以外的模糊缩写(如 "CST"、"PST"),它们可能有歧义或不可靠。推荐使用:
TimeZone.getTimeZone("GMT")TimeZone.getTimeZone("UTC")-
ZoneId.of("GMT")或ZoneId.of("UTC")


















