java 时间 时区
所属分类 java
浏览量 11
java 时间 时区
System.currentTimeMillis()
java.time.LocalDateTime
java.util.Date
java.time.Instant 表示时间戳
java.util.Date 和 java.time.LocalDateTime 的区别
System.currentTimeMillis() 是否跟时区有关
java.time.Instant 用法 及 与 System.currentTimeMillis()的区别
在Java 8及以上版本的新项目中,
官方和业界都强烈推荐使用 java.time 包下的新API,除非需要维护旧的遗留代码。
System.currentTimeMillis() 的返回值与时区完全无关。
返回的是一个 long 类型的数值,表示自协调世界时(UTC) 的1970年1月1日午夜(即Unix纪元)到当前时刻所经过的毫秒数。
这个毫秒数是一个绝对值,是时间轴上的一个固定点。
无论程序运行在哪个时区,只要时间点相同,调用此方法返回的数值就完全一样
当执行 new Date(System.currentTimeMillis()) 并打印 Date 对象时,
看到的字符串(如 "Wed Aug 26 15:00:00 CST 2026")会显示你所在时区(如CST)的时间。
这并不是因为 Date 对象存储了时区信息,而是因为 Date 的 toString() 方法
在将那个绝对的毫秒数转换为可读的日期时间字符串时,
自动使用了系统的默认时区进行格式化
java.time.Instant 的核心用法
Instant 是 java.time 包中用来替代 java.util.Date 的核心类,
它表示时间轴上的一个瞬时点,精度达到纳秒级别。
// 1. 获取当前时刻(最常用)
Instant now = Instant.now(); // 例如:2026-08-26T07:00:00.123456789Z
// 2. 从 System.currentTimeMillis() 的 long 值创建
Instant fromMillis = Instant.ofEpochMilli(System.currentTimeMillis());
// 3. 从秒数创建(自1970-01-01T00:00:00Z起的秒数)
Instant fromSeconds = Instant.ofEpochSecond(1_700_000_000L);
Instant now = Instant.now();
// 1. 获取毫秒级时间戳(等同于 System.currentTimeMillis())
long millis = now.toEpochMilli();
// 2. 获取秒级时间戳
long seconds = now.getEpochSecond();
// 3. 加减时间(返回新 Instant,不可变)
Instant later = now.plusSeconds(60); // 加60秒
Instant earlier = now.minus(2, ChronoUnit.HOURS); // 减2小时
// 4. 比较先后
boolean isAfter = now.isAfter(earlier); // true
// 5. 转换为带时区的人类可读时间
ZonedDateTime zdt = now.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zdt); // 2026-08-26T15:00:00.123+08:00[Asia/Shanghai]
// Date -> Instant
Date oldDate = new Date();
Instant instant = oldDate.toInstant();
// Instant -> Date
Date newDate = Date.from(instant);
jvm如何设置时区
// 1. 设置JVM默认时区(影响所有使用默认时区的代码)
TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
// 2. 或者,使用 java.time 包,在具体操作时指定时区(更精确,不影响全局)
ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
Instant.now().atZone(ZoneId.of("Asia/Shanghai"));
java -Duser.timezone=Asia/Shanghai -jar your-app.jar
java -Duser.timezone=UTC -jar your-app.jar
TimeZone.getDefault() 方法会读取系统属性 user.timezone 的值。
System.out.println("默认时区: " + TimeZone.getDefault().getID());
System.out.println("user.timezone: " + System.getProperty("user.timezone"));
System.out.println("当前时间: " + new Date());
System.out.println("Instant: " + Instant.now());
Instant toString方法
public String toString() {
return DateTimeFormatter.ISO_INSTANT.format(this);
}
DateTimeFormatter.ISO_INSTANT 是一个不可变、线程安全的格式化器,
用于将 Instant(时间戳)格式化为符合 ISO-8601 标准的字符串。
输出格式:YYYY-MM-DDTHH:mm:ss.SSSSSSSSSZ
固定时区:始终使用 UTC 时区(即 Z 后缀,代表零时区)
精度:支持纳秒级精度(最多9位小数),但会自动截断末尾多余的零
System.out.println(LocalDateTime.now()+"");
System.out.println(System.currentTimeMillis());
System.out.println(new Date());
System.out.println("默认时区: " + TimeZone.getDefault().getID());
System.out.println("user.timezone: " + System.getProperty("user.timezone"));
System.out.println("当前时间: " + new Date());
System.out.println("Instant: " + Instant.now());
2026-08-26T16:25:40.769669400
1787732740771
Wed Aug 26 16:25:40 CST 2026
默认时区: Asia/Shanghai
user.timezone: Asia/Shanghai
当前时间: Wed Aug 26 16:25:40 CST 2026
Instant: 2026-08-26T08:25:40.796670Z
上一篇
《道德经》和《清静经》
ETF超市战法
知足不辱,知止不殆