108

我有一个纪元秒和一个zoneId(见method1下文)。

可以LocalDateTime使用系统默认 zoneId 转换为,但我找不到将纪元秒转换为LocalDateTime(见 method2下文)的方法,因为没有ZoneOffset.systemDefault. 我认为这很模糊。

import java.time.{Instant, LocalDateTime, ZoneId, ZoneOffset}

val epochSecond = System.currentTimeMillis() / 1000

// method1
LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault())

// method2
LocalDateTime.ofEpochSecond(epochSecond, 0, ZoneOffset.MAX)

笔记

上面提供的源代码是Scala

4

9 回答 9

132

以下是您可以从中获取ZoneOffset的方法ZoneId

Instant instant = Instant.now(); //can be LocalDateTime
ZoneId systemZone = ZoneId.systemDefault(); // my timezone
ZoneOffset currentOffsetForMyZone = systemZone.getRules().getOffset(instant);

注意:ZoneId可能有不同的偏移量,具体取决于时间点和特定地点的历史。所以选择不同的 Instant 会导致不同的偏移量。

NB2:ZoneId.of()可以返回 aZoneOffset而不是ZoneIdif UTC+3/ GMT+2/etc 被传递,而不是像Africa/Cairo. Instant因此,如果通过了 UTC/GMT 偏移量,则不会考虑历史/地理/夏令时信息- 您只需使用指定的偏移量即可。

于 2016-05-28T16:43:13.777 回答
45

没有一对一的映射。ZoneId 定义了一个地理范围,其中随着时间的推移使用一组不同的 ZoneOffset。如果时区使用夏令时,则其 ZoneOffset 在夏季和冬季之间会有所不同。

此外,夏令时规则可能会随着时间而改变,因此 ZoneOffset 可能会有所不同,例如 2015 年 13 月 10 日与 1980 年 10 月 13 日。

因此,您只能在特定 Instant 上找到 ZoneId 的 ZoneOffset。

另见https://en.wikipedia.org/wiki/Tz_database

于 2015-09-17T09:41:04.310 回答
43
于 2017-01-11T21:16:35.630 回答
10

正如文档所说,“这主要用于低级转换,而不是一般应用程序使用。”

通过Instant对我来说非常有意义-您的纪元秒实际上是 an 的不同表示Instant,因此转换为 anInstant然后将其转换为特定的时区。

于 2015-09-17T09:29:31.393 回答
9

I hope the first two lines of my solution below are helpful. My problem was I had a LocalDateTime and the name of a time zone, and I needed an instant so I could build a java.util.Date, because that's what MongoDB wanted. My code is Scala, but it's so close to Java here I think there should be no problem understanding it:

val zid = ZoneId.of(tzName)                                // "America/Los_Angeles"
val zo: ZoneOffset = zid.getRules.getOffset(localDateTime) // ⇒ -07:00
                                         // 2017-03-16T18:03

val odt = OffsetDateTime.of(localDateTime, zo) // ⇒ 2017-03-16T18:03:00-07:00
val instant = odt.toInstant                    // ⇒ 2017-03-17T01:03:00Z
val issued = Date.from(instant)
于 2017-03-16T19:12:34.437 回答
3

The following returns the amount of time in milliseconds to add to UTC to get standard time in this time zone:

TimeZone.getTimeZone(ZoneId.of("Europe/Amsterdam")).getRawOffset()
于 2018-01-05T10:12:48.487 回答
2

I have an epoch second and a zoneId. Is there any way to convert ZoneId to ZoneOffset in java 8?

  1. Get ZonedDateTime from epoch second and Zone Id
  2. Get ZoneOffset from ZonedDateTime

Demo:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        // Get ZonedDateTime from epoch second and Zone Id
        ZonedDateTime zdt = Instant.ofEpochSecond(1597615462L).atZone(ZoneId.of("Europe/London"));

        // Get ZoneOffset from ZonedDateTime
        ZoneOffset offset = zdt.getOffset();

        System.out.println(offset);
    }
}

Output:

+01:00
于 2020-08-16T22:11:53.557 回答
0

Since you are looking for the default zone offset

ZonedDateTime.now().getOffset()
于 2021-10-12T11:49:15.763 回答
0

This does it without creating an Instant or such objects to pull it out.

public static ZoneOffset offset() {
    return offset(ZoneId.systemDefault());                 // Default system zone id
}
public static ZoneOffset offset(ZoneId id) {
    return ZoneOffset.ofTotalSeconds((int) 
        TimeUnit.MILLISECONDS.toSeconds(
            TimeZone.getTimeZone(id).getRawOffset()        // Returns offset in milliseconds 
        )
    );
}
于 2021-12-11T12:14:56.510 回答