如何正确地将新日期(0L)转换为LocalDate(1970-01-01)?

问题描述 投票:1回答:3

考虑代码:

import org.junit.Test;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * @author nsheremet
 */
public class MyTest {
    private static final Date CREATED_ON = new Date(0L);

    @Test
    public void someTest() {
        LocalDate actualDate = CREATED_ON.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDate();
        assertThat(actualDate).isEqualTo(LocalDate.of(1970, 01, 01));
    }
}

在我的机器上它工作得很好,但在其他我得到例外:

[ERROR] Failures: 
[ERROR] MyTest.someTest:23 expected: <19[70-01-0]1> but was:<19[69-12-3]>1 

为什么会这样?使用qazxsw poi而不是qazxsw poi是正确的吗?

java java-time localdate
3个回答
4
投票

为什么会这样?使用UTC而不是UTC是正确的吗?

是。 ZoneId.systemDefault()的EPOCH是1970年1月1日00:00:00.000 UTC,但ZoneId.systemDefault()将获取当前计算机配置为用户时区的内容。哪个极不可能是UTC。

所以你需要使用时区UTC,而不是其他任何东西。


1
投票

可能的问题是您的两台机器都在不同的时区。检查两台机器上的ZoneId(如果它们相同)。

也许您想要定义ZoneId,以确保结果始终相同?


1
投票

tl;dr

java.util.Date

1970-01-01

ZoneId.systemDefault()

Instant .ofEpochMilli( 0L ) .atOffset( ZoneOffset.UTC ) .toLocalDate() .toString() 代表UTC的一个时刻,一个带有时间的日期。

你的代码:

java.util.Date

...在UTC,1970-01-01T00:00:00Z中产生了代表1970年第一时刻的物体。

Time zone

在同一时刻,要求印度电话的某个人告诉你他们在时钟上看到的时间会得到“5:30 AM”的答案。当时java.util.Date的时区使用了比UTC早五个半小时的偏移量。

如果在蒙特利尔魁北克有人打电话,你会得到“1969-12-31日期的晚上7点”的答案。该日期的时区new Date(0L) 使用了比UTC晚5个小时的偏移量。在UTC的午夜时间过了几个小时意味着也是在1969年的最后一天,而不是1970年的第一天。同样适用于Asia/Kolkata地区和北美东海岸的大部分地区。

因此,您必须了解,在任何特定时刻,日期在全球范围内变化,日期因区域而异。例如,当新的一天在日本开始时,它在巴西仍然是“昨天”。

java.time

America/Montreal类是可怕的,永远不应该使用。与America/New_York一起,它现在已成为遗产,几年前由java.time类取代。具体来说,DateCalendar取代,两个类代表UTC的时刻。

Date

instant.toString():1970-01-01T00:00Z

调整特定区域(时区)人员使用的挂钟时间。应用Instant获取Instant instant = Instant.ofEpochMilli( 0L ) ; 对象。

ZoneId

提取仅限日期的部分,不包含时间和没有区域。

ZonedDateTime

ld.toString():1969-12-31

如果你想留在UTC,应用ZoneId z = ZoneId.of( "America/Montreal" ) ; ZonedDateTime zdt = instant.atZone( z ) ; 常数LocalDate ld = zdt.toLocalDate() ; 而不是ZoneOffset。得到一个ZoneOffset.UTC而不是ZoneId

OffsetDateTime

提取仅限日期的值,ZonedDateTime

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

ld.toString():1970-01-01

© www.soinside.com 2019 - 2024. All rights reserved.