简体   繁体   English

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

[英]How to properly convert new Date(0L) to LocalDate (1970-01-01)?

Consider code: 考虑代码:

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));
    }
}

On my machine it works good but on other I got en exception: 在我的机器上,它运行良好,但在其他机器上却出现异常:

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

Why it happens? 为什么会发生? Using UTC instead of ZoneId.systemDefault() is corrent? 使用UTC代替ZoneId.systemDefault()是否正确?

Why it happens? 为什么会发生? Using UTC instead of ZoneId.systemDefault() is correct? 使用UTC代替ZoneId.systemDefault()是正确的吗?

Yes. 是。 EPOCH for java.util.Date is January 1st, 1970 00:00:00.000 UTC , But ZoneId.systemDefault() will fetch what the current computer is configured to use as user time zone. java.util.Date EPOCH是1970年1月1日UTC ,但是ZoneId.systemDefault()将获取当前计算机配置为用作用户时区的内容。 Which is extremely unlikely to be UTC. 这极不可能是UTC。

So you need to use time zone UTC, rather than anything else. 因此,您需要使用时区UTC,而不是其他任何时间。

The possible problem is that your both machines are in different time zones. 可能的问题是您的两台计算机都位于不同的时区。 Check the ZoneId on both machines (if they are the same). 检查两台计算机上的ZoneId(如果它们相同)。

Maybe you want to put defined ZoneId, to ensure that results will always be the same? 也许您想放置定义的ZoneId,以确保结果始终相同?

tl;dr tl; dr

Instant
.ofEpochMilli( 0L ) 
.atOffset( 
    ZoneOffset.UTC
)
.toLocalDate()
.toString()

1970-01-01 1970-01-01

java.util.Date

java.util.Date represents a moment in UTC, a date with a time-of-day. java.util.Date表示UTC java.util.Date的时刻,带有日期的日期。

Your code: 您的代码:

new Date(0L)

…produced an object representing the first moment of 1970 in UTC, 1970-01-01T00:00:00Z. …在UTC 1970-01-01T00:00:00Z中产生了代表1970年第一刻的对象。

Time zone 时区

At that same moment, asking someone on the phone in India to tell you the time-of-day they see on the clock would get you an answer of “5:30 AM”. 同时,在印度打电话询问某人在时钟上看到的时间,您会得到“ 5:30 AM”的答复。 The time zone Asia/Kolkata at that moment used an offset of five and a half hours ahead of UTC. 当时Asia/Kolkata的时区比世界Asia/Kolkata时间了五个半小时。

If on the phone with someone in Montréal Québec, you would get the answer of “7 PM… of the date 1969-12-31”. 如果与蒙特利尔魁北克省的某人通电话,您会得到“ 1969-12-31日期的晚上7点…”的答案。 The time zone America/Montreal on that date used an offset of five hours behind UTC. 该日期的America/Montreal时区比世界标准时间了五个小时。 Being hours behind midnight in UTC means being on the date behind too, the last day of 1969 rather than the first day of 1970. Ditto for the zone America/New_York and much of the east coast of North America. 在UTC的午夜时分之后的几个小时也意味着在1969年的最后一天而不是1970年的第一天。在America/New_YorkAmerica/New_York大部分东海岸的同上。

So, you must understand that for any given moment, the date varies around the globe, the date varies by zone. 因此,您必须了解,在任何给定时刻,日期在全球范围内都会有所不同,日期会因区域而异。 When a new day dawns in Japan, it is still “yesterday” in Brazil, for example. 例如,当日本出现新的一天时,在巴西仍然是“昨天”。

java.time java.time

The Date class is terrible, and should never be used . Date类很糟糕, 永远不要使用 Along with Calendar it is now legacy, supplanted years ago by the java.time classes. 现在,它与Calendar已成为遗留物,几年前被java.time类所取代。 Specifically, Date is replaced by Instant , both classes representing a moment in UTC. 具体来说, DateInstant替换,这两个类都表示UTC的时刻。

Instant instant = Instant.ofEpochMilli( 0L ) ;

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

Adjust into the wall-clock time used by the people of a particular region, a time zone. 将特定地区的人使用的挂钟时间调整为一个时区。 Apply a ZoneId to get a ZonedDateTime object. 应用ZoneId以获取ZonedDateTime对象。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Extract the date-only portion, without the time-of-day and without the zone. 提取仅日期部分,没有时间和区域。

LocalDate ld = zdt.toLocalDate() ;

ld.toString(): 1969-12-31 ld.toString():1969-12-31

If you want to stay in UTC, apply a ZoneOffset constant of ZoneOffset.UTC instead of a ZoneId . 如果你想留在UTC,应用ZoneOffset不断ZoneOffset.UTC代替ZoneId And get an OffsetDateTime rather than a ZonedDateTime . 并获取一个OffsetDateTime而不是ZonedDateTime

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

Extract the date-only value, a LocalDate . 提取仅日期的值LocalDate

LocalDate ld = odt.toLocalDate() ;

ld.toString(): 1970-01-01 ld.toString():1970-01-01

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 java.sql.Timestamp 在 1970-01-01 之后返回负值 - why java.sql.Timestamp return negative value when the date is after 1970-01-01 为什么我的 SQLite 查询将系统日期返回为 1970-01-01? - Why is my SQLite query returning the system date as 1970-01-01? 如何从Java中的纪元(1970-01-01)获得毫秒? - How do I get milliseconds from epoch (1970-01-01) in Java? 将完整的Java日期(例如,2013年6月19日上午8.00)转换为一个时间(即1970-01-01上午8.00) - Convert a full Java date (e.g. 8.00am 2013-06-19) to just a time (i.e. 8.00am 1970-01-01) oracle:如何将类似“ 2000-01-01T01:01:01”的字符串转换为Date? - oracle: how to convert string like '2000-01-01T01:01:01' to Date? JMeter:Sampler结果显示“ Sample Start:1970-01-01 05:30:00 IST” - JMeter: Sampler results shows “Sample Start: 1970-01-01 05:30:00 IST” 如何在Java中的LocalDate数据类型中从oracle(格式“01-JAN-19”)转换Date数据类型 - How to convert Date data type from oracle ( format “ 01-JAN-19”) in LocalDate data type in Java 日期 d = 新日期(0L); 这个日期的 0L 是什么意思? - Date d = new Date(0L); what is 0L mean in this Date? 为什么新的日期(0L)不会返回零日期 - How come new Date(0L) doesn't return zero date 以日期时间格式转换纪元日期1980-01-01 - Convert Epoch Date in Date time format 1980-01-01
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM