在 java.time 中的 ZonedDateTime 上设置时间?

Posted

技术标签:

【中文标题】在 java.time 中的 ZonedDateTime 上设置时间?【英文标题】:Set the time-of-day on a ZonedDateTime in java.time? 【发布时间】:2016-08-22 12:30:24 【问题描述】:

如何更改现有ZonedDateTime 对象的时间部分?我想保留日期和时区,但要更改小时和分钟。

【问题讨论】:

【参考方案1】:

tl;博士

zdt.with ( LocalTime.of ( 16 , 15 ) )

不可变对象

java.time 类使用Immutable Objects 模式来创建新对象,而不是更改(“变异”)原始对象。

with()

ZonedDateTime::with 方法是一种灵活的方法,可以基于另一个生成新的ZonedDateTime,但有一些特殊的区别。您可以传递任何实现TemporalAdjustor 接口的对象。

在这种情况下,我们只想更改时间。 LocalTime 对象表示没有任何日期和任何时区的时间。而LocalTime 实现了TemporalAdjustor 接口。因此,仅应用该时间值,同时保持日期和时区不变。

ZonedDateTime marketOpens = ZonedDateTime.of ( LocalDate.of ( 2016 , 1 , 4 ) , LocalTime.of ( 9 , 30 ) , ZoneId.of ( "America/New_York" ) );
ZonedDateTime marketCloses = marketOpens.with ( LocalTime.of ( 16 , 0 ) );

再次检查时间跨度的持续时间是否符合预期,六个半小时。

Duration duration = Duration.between ( marketOpens , marketCloses );

转储到控制台。

System.out.println ( "marketOpens: " + marketOpens + " | marketCloses: " + marketCloses + " | duration: " + duration );

市场开放时间:2016-01-04T09:30-05:00[America/New_York] |市场关闭时间:2016-01-04T16:00-05:00[America/New_York] |持续时间:PT6H30M

请记住,在此示例中,我们还隐式调整时间中的秒和小数秒LocalTime 对象带有小时、分钟、秒和小数秒。我们指定了一个小时和一分钟。在构建LocalTime 期间,我们省略了秒和小数秒导致默认值0。应用LocalTime 的所有四个方面来获得我们新鲜的ZonedDateTime

不少类实现了TemporalAdjustor 接口。请参阅该类文档上的列表,包括 LocalDateMonthYear 等。因此,您可以传递其中任何一个来更改日期时间值的该方面。

阅读 Hochschild 的评论。当您指定对特定日期和区域无效的时间时,您必须了解该行为。例如,在夏令时 (DST) 转换期间。

【讨论】:

正确示例。但是,市场开盘和收盘时间通常定义为当地时间,而不是 UTC 时间戳,因此LocalDateTimeLocalTime 类型通常更匹配(并且还提供with() 方法)。但是,如果您仍然坚持使用ZonedDateTime,那么如果在夏季-冬季时间切换期间设置的时间与您最终在结果对象中观察到的时间有所不同,请不要太惊讶,因为 JSR-310 可以使自动调整(推进策略),诚然这是一种罕见的情况,在市场时代极不可能发生......

以上是关于在 java.time 中的 ZonedDateTime 上设置时间?的主要内容,如果未能解决你的问题,请参考以下文章

Java日期时间API系列33-----Jdk8中java.time包中的新的日期时间API类应用,格式化常用模板大全,新增Excel常用格式。

Java日期时间API系列11-----Jdk8中java.time包中的新的日期时间API类,使用java8日期时间API重写农历LunarDate

Java日期时间API系列32-----Jdk8中java.time包中的新的日期时间API类应用,时间工具包 xk-time 1.0.0 版本完成。

用java.time包中的Clock类得出的当前时间不对

在 SQLite 数据库中存储 java.time.OffsetDateTime 的推荐方法

Java日期时间API系列20-----Jdk8中java.time包中的新的日期时间API类,ZoneId时区ID大全等。