How to create a Date object, using UTC, at a speci

2020-04-11 09:38发布

Is it possible to create a java.util.Date object that is guaranteed to be UTC and at a specific time in the past, like an hour ago or a day ago, and is this a good idea?

I have reviewed the Stack Overflow question get date as of 4 hours ago and its answers. But I want to avoid having to add more dependencies, like jodaTime, and the accepted answer uses System.currentTimeMillis() which would be the local timezone, would it not?

标签: java date utc
2条回答
三岁会撩人
2楼-- · 2020-04-11 10:14

You can achieve this using the java.time package, as follows:

LocalDateTime localDateTime = LocalDateTime.now(ZoneOffset.UTC).minusHours(4);
Date date = Date.from(localDateTime.atZone(ZoneOffset.UTC).toInstant());

Gives the following output:

2018-01-31T14:58:28.908
Wed Jan 31 20:28:28 IST 2018     //20:28:28 IST is 14:58:28 UTC

Which is correctly 4+5:30 hours behind my current time - Asia/Kolkata ZoneId.

查看更多
Ridiculous、
3楼-- · 2020-04-11 10:37

As discussed vividly in the comments, the recommendation is to use the java.time package. The easy solution:

Instant fourHoursAgo = Instant.now().minus(Duration.ofHours(4));
System.out.println(fourHoursAgo);

This just printed

2018-01-31T14:57:44.667255Z

Since UTC time is now 18:58, the output is what you asked for. The Instant itself is offset neutral. Its toString delivers time in UTC, but there was no mention of UTC in producing the Instant, so whether it gives you what you want, I am not sure. I will give you a result that is explicitly in UTC later.

But first, if you do need a java.util.Date, typically for a legacy API that you cannot change, the conversion is easy:

Date oldfashionedDate = Date.from(fourHoursAgo);
System.out.println(oldfashionedDate);

On my computer in Europe/Copenhagen time zone this printed:

Wed Jan 31 15:57:44 CET 2018

Again, this agrees with the time four hours before running the snippet. And again, a Date doesn’t have a UTC offset in it. Only its toString method grabs my JVM’s time zone setting and uses it for generating the string, this does not affect the Date. See the Stack Overflow question, How to set time zone of a java.util.Date?, and its answers.

As promised, if you do need to represent not only the time but also the offset, use an OffsetDateTime:

OffsetDateTime fourHoursAgoInUtc = OffsetDateTime.now(ZoneOffset.UTC).minusHours(4);
System.out.println(fourHoursAgoInUtc);

This printed

2018-01-31T14:57:44.724147Z

Z at the end means offset zero from UTC or “Zulu time zone” (which isn’t a true time zone). The conversion to a Date is not much more complicated than before, but again, you will lose the offset information in the conversion:

Date oldfashionedDate = Date.from(fourHoursAgoInUtc.toInstant());
System.out.println(oldfashionedDate);

This printed:

Wed Jan 31 15:57:44 CET 2018

Link: Oracle tutorial explaining how to use java.time

查看更多
登录 后发表回答