3

我想知道我的LocalDateTime实例是否拥有本地日期和时间或 UTC 日期和时间(如DateTime.KindC# 中的属性)

LocalDateTime date1=LocalDateTime.now(); // it is local

LocalDateTime date2=LocalDateTime.now(ZoneId.of("UTC")); // it is UTC

(date1.getKind() == Kind.UTC || date1.getKind() == Kind.Local)Java一样的东西吗?

4

2 回答 2

7

LocalDateTime对象本身不存储时区信息——它只有日期和时间相关字段:日、月和年;小时、分钟、秒和纳秒。但是该now方法使用时区或偏移量来获取这些字段的正确值。

这是因为“今天是星期几?”这些问题的答案。“现在几点了?” 并不像我们想象的那么简单。

通常认为答案就像查看我们的日历/手机/其他任何东西并查看当前日期/时间一样简单。但技术上正确的答案是:“视情况而定”

这基本上取决于你在哪里。此时此刻,世界上每个地方都有自己的本地日期和时间。例如,2017年7 月 5:圣保罗是 14 小时(或下午 2 点),伦敦是下午 6 点,UTC 是下午 5 点,但东京是第二天凌晨 2 点(7 月 6) ) .

世界上每个地区都有特定的规则来确定他们在历史上的当地时间,当然这会影响他们的当地日期。将国家/城市/地区映射到这些规则的概念是时区

这就是该now方法需要时区的原因。该ZoneId对象加载所有时区数据以检查该区域中的当前日期和时间,并相应地调整日/月/年/小时/分钟/秒/纳秒值。不接收参数 ( LocalDateTime.now()) 的版本将使用系统默认时区,因此 API 最终总是使用某个时区。

时区(或偏移量ZoneOffset.UTC,例如LocalDateTime- 丢弃。

因此,这个概念可能与您的想法有些不同。如果我做:

// ZoneOffset.UTC is equivalent to ZoneId.of("UTC")
LocalDateTime date = LocalDateTime.now(ZoneOffset.UTC);

这段代码的作用是:“以 UTC 格式获取当前日期和时间,只获取日期和时间字段,丢弃时区/偏移信息”

当我运行此代码时,UTC 中的当前日期/时间为2017-09-25T12:15:43.570Z,因此LocalDateTime的值等于2017-09-25T12:15:43.570(没有任何时区信息,只有日期和时间字段)。如果我now()不带参数调用,它将使用 JVM 默认时区(在我的情况下,它是America/Sao_Paulo),并且值将是2017-09-25T09:15:43.570.

因此,LocalDateTime您可以使用 a 获取值,但您无法知道这些值来自哪个时区,因为它不会保留此信息。

如果您想要 UTC 日期,则必须使用其他类,旨在保留此信息:

  • Instant.now()- 这将始终获得当前的 UTC 时刻
  • OffsetDateTime.now(ZoneOffset.UTC)- 使用它您可以查询日期和时间字段(例如getDayOfMonth()getHour()
  • ZonedDateTime.now(ZoneOffset.UTC)- 对于 UTC,它与 相同OffsetDateTime,但如果您使用不同的时区,它会处理所有时区特定数据,例如夏令时更改。

要检查此类对象是否为 UTC,一种方法是使用以下getZone()方法:

ZonedDateTime z = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(z.getZone().equals(ZoneOffset.UTC)); // true

但是如果你使用等价物ZoneId.of("UTC")equals方法返回false。因此,您还可以检查是否z.getZone().getId()等于ZUTC。与OffsetDateTime类似:

OffsetDateTime odt = OffsetDateTime.now(ZoneOffset.UTC);
System.out.println(odt.getOffset().equals(ZoneOffset.UTC)); // true

Instant你不需要检查,因为它总是在UTC 。

您可以在Oracle 的日期/时间教程中查看所有可用的类型。


两者ZonedDateTimeOffsetDateTime都可以LocalDateTime使用以下toLocalDateTime()方法转换为:

// dt will have the current date and time in UTC
LocalDateTime dt = ZonedDateTime.now(ZoneOffset.UTC).toLocalDateTime();

// or
LocalDateTime dt = OffsetDateTime.now(ZoneOffset.UTC).toLocalDateTime();

这样,该dt变量将具有与 UTC 中的当前日期/时间相对应的所有日期和时间字段(日/月/年、小时/分钟/秒/纳秒)。但它不会保留任何时区/偏移信息,因此LocalDateTime对象本身无法知道这些值来自哪个时区。

于 2017-09-25T12:31:55.560 回答
0

我意识到这个问题有点老了,但我正在学习 Java,发现自己正在尝试做一些非常相似的事情。经过一番阅读,我发现我可以用这个做你所要求的:

    public static void main (String args[]) {
    LocalDateTime now = LocalDateTime.now(Clock.systemDefaultZone()); // The clock argument is not really needed here.

    String pattern = "dd MMM yyyy HH:mm:ss"; // Setup your format for output
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
    System.out.println("Local time is: " + dtf.format(now));

    LocalDateTime utc = LocalDateTime.now(Clock.systemUTC()); // Define alternate timezone
    System.out.println("GMT/UTC is: "+dtf.format(utc));
}
于 2019-08-27T20:00:58.117 回答