Java
Python前端运维数据库
Java
Java
  • 新特性
    • Record
    • Optional
  • 面向对象
    • 面向对象基础
    • 构造方法
    • 继承与多态
    • 接口
    • 修饰符
    • 代码块
    • 接口(Interface)
    • 枚举类
  • IO流
    • IO
      • 字节流
      • 字符流
      • 缓冲流
      • 转换流
      • 操作ZIP
      • File 对象
    • NIO
      • Channel和Buffer
      • 异步文件通道AsynchronousFileChannel
      • Selector
      • Path/Files/Pipe
  • 反射
  • 内存分配
  • 集合
    • 简介
    • List
    • Set
    • Map
    • EnumMap
  • 日期与时间
    • Date和Calendar
    • Java8 新时间 ✨
      • LocalDateTime
      • ZonedDateTime
      • Duration
    • 时间格式化
      • SimpleDateFromat
      • DateTimeFormatter ✨
    • Instant
    • 实践
  • 网络编程
    • IP 地址
    • 网络模型
    • TCP 编程
    • UDP 编程
    • HTTP 编程
  • 加密和安全
  • 并发编程
    • 多线程
    • 线程与进程的区别
    • 线程组和线程优先级
    • 线程池
    • 线程锁
  • 异步任务
    • Future
    • CompletableFuture
      • 开启异步任务
      • 串行任务方法
      • 并行任务方法
      • 任务结束方法
      • 异常处理方法
      • 查看状态方法
      • 设置任务结果方法
  • 执行系统命令
  • Stream 流
    • Stream 流的创建
    • Stream 流串行与并行
    • Stream 流中间操作
    • Stream 流终端操作
  • Lambda 表达式
    • Lambda 表达式简介
    • Lambda 表达式语法
    • 方法引用
  • String
  • StringBuffer
由 GitBook 提供支持
在本页

这有帮助吗?

  1. 日期与时间
  2. Java8 新时间 ✨

ZonedDateTime

LocalDateTime总是标识本地日期和时间,要表示一个带时区的日期和时间,我们就需要ZonnedDateTime。

可以简单的把ZonedDateTime理解成LocalDatetime加ZoneId。ZoneId是java.time引入的新的时区类,注意和旧的java.util.TimeZone区别。

要创建一个ZonedDateTime对象,有以下几种方法,一种是通过now()方法返回当前时间:

ZonedDateTime zonedDateTime = ZonedDateTime.now();  // 默认时区
ZonedDateTime zonedDateTime1 = ZonedDateTime.now(ZoneId.of("America/New_York"));  // 指定时区
System.out.println(zonedDateTime);      // 2023-08-26T17:48:47.378072+08:00[Asia/Shanghai]
System.out.println(zonedDateTime1);     // 2023-08-26T05:48:47.378924-04:00[America/New_York]

通过观察打印的两个ZonedDateTime,发现它们时区不同,但表示的时间都是同一时刻(毫秒数不同是执行语句时的时间差)。

另一种方式是通过给一个LocalDateTime附加一个ZoneId,就可以变成ZonedDateTime。

LocalDateTime localDateTime = LocalDateTime.of(2015, 5, 10, 11, 22, 33);
ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
ZonedDateTime zonedDateTime2 = localDateTime.atZone(ZoneId.of("Europe/London"));
System.out.println(zonedDateTime);      // 2015-05-10T11:22:33+08:00[Asia/Shanghai]
System.out.println(zonedDateTime2);     // 2015-05-10T11:22:33+01:00[Europe/London]

以这种方式创建的ZonedDateTime,它的日期和时间与LocalDateTime相同,但附加的时区不同,因此是两个不同的时刻。

时区转换

要转换时区,首先我们需要有一个ZonedDateTime对象,然后,通过withZoneSameInstant()将关联时区转换到另一个时区,转换后日期和时间都会相应调整。

// 以中国时区获取当前时间:
ZonedDateTime zbj = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
// 转换为纽约时间:
ZonedDateTime zny = zbj.withZoneSameInstant(ZoneId.of("America/New_York"));
System.out.println(zbj);  // 2023-08-26T17:55:47.001301+08:00[Asia/Shanghai]
System.out.println(zny);  // 2023-08-26T05:56:02.208144-04:00[America/New_York]

要特别注意,时区转换的时候,由于夏令时的存在,不同的日期转换的结果很可能是不同的。这是北京时间9月15日的转换结果:

2019-09-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-09-15T09:05:50.187697-04:00[America/New_York]

这是北京时间11月15日的转换结果:

2019-11-15T21:05:50.187697+08:00[Asia/Shanghai]
2019-11-15T08:05:50.187697-05:00[America/New_York]

两次转换后的纽约时间有1小时的夏令时时差。

有了ZonedDateTime,将其转换为本地时间就非常简单:

ZonedDateTime zdt = ...
LocalDateTime ldt = zdt.toLocalDateTime();

转换为LocalDateTime时,直接丢弃了时区信息。

上一页LocalDateTime下一页Duration

最后更新于3个月前

这有帮助吗?