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 g
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
.
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