Answer by deHaar 通常是正确的,并且明智地利用了现代 java.time 类。但是,我会使用稍微不同的方法。
tl;博士
OffsetDateTime.of( // Represent a moment as a date, a time-of-day, and an offset-from-UTC.
LocalDate.now( ZoneOffset.UTC ) , // Current date as seen right now in UTC. Beware: For any given moment, the date varies around the globe by zone.
LocalTime.parse( "12:15:00" ) , // Your specified time-of-day.
ZoneOffset.UTC // An offset of zero hours-minutes-seconds, for UTC itself.
) // Returns an `OffsetDateTime` object.
.atZoneSameInstant( // Adjust from UTC to a time zone. Same moment, different wall-clock-time.
ZoneId.of( "America/Port_of_Spain" ) ; // One of the many time zones that are behind UTC by four hours on that date.
) // Returns a `ZonedDateTime` object.
.toLocalTime() // Extract the time-of-day only, leaving behind the date and the zone.
时区
我的时区是 GMT-4
不。那不是时区。
值GMT-4 仅代表offset-from-UTC。 UTC 基线之前或之后的小时-分钟-秒数。
时区更多。时区有一个名字,代表了过去、现在和未来的历史变化,特定地区的人们使用的偏移量。因此,时区总是比单纯的偏移更可取。
以Continent/Region 的格式指定proper time zone name,例如America/Montreal、Africa/Casablanca 或Pacific/Auckland。切勿使用 2-4 个字母的缩写,例如 EST 或 IST,因为它们不是真正的时区,没有标准化,甚至不是唯一的 (!)。
ZoneId z = ZoneId.of( "Africa/Casablanca" ) ;
如果您的时区当前比 UTC 晚 4 小时,则您必须位于 America/Aruba、America/Puerto_Rico、America/Manaus、America/Martinique 等时区。
ZoneId z = ZoneId.of( "America/Martinique" ) ;
UTC
我有格式为 (HH: mm: ss) 的 UTC 字符串
不。
"12:15:00" 等值不能说是 UTC 值。没有日期,该值就没有真正的意义。时刻由三部分组成:
- 一个日期,
- 一天中的某个时间,并且
- 偏移量/区域。
说“UTC 中午”只给了我们 3 个部分中的 2 个。日期不见了。
今天……什么概念
也许您想将该时间应用到当前日期,如 UTC 所示。
LocalDate todayUTC = LocalDate.now( ZoneOffset.UTC ) ;
请记住,在任何特定时刻,全球各地的日期都会因地区而异。此时此刻,日本东京的日期是“明天”,而美国俄亥俄州托莱多的日期仍然是“昨天”。
OffsetDateTime
将所有三个组合成一个OffsetDateTime 对象:日期、时间和偏移量/区域。
LocalTime localTime = LocalTime.parse( "12:15:00" ) ;
OffsetDateTime odt = OffsetDateTime.of( todayUTC , localTime, ZoneOffset.UTC ) ;
ZonedDateTime
从 UTC 调整到您的特定时区。同一时刻,时间线上的同一同时点,不同的挂钟时间。应用ZoneId 以获取ZonedDateTime 对象。时区现在知道Daylight Saving Time (DST) 是否以及何时适用于该特定时区,并进行相应调整。
ZoneId z = ZoneId.of( "America/Martinique" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
错误的方法
您不应该从LocalTime 中添加/减去一些小时数。在某些区域的某些日期,特定时间可能不存在。例如,对于夏令时,在美国的“Spring-ahead”这一天,不存在 02:15:00 的时间,因为时钟从 02:00:00 开始向前跳到 03:00:00。
使用ZonedDateTime 类的正确方法将自动进行相应调整。