[英]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,以确保结果始终相同?
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年第一刻的对象。
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_York
和America/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.
例如,当日本出现新的一天时,在巴西仍然是“昨天”。
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. 具体来说,
Date
被Instant
替换,这两个类都表示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.