How to create a Date object, using UTC, at a specific time in the past?

后端 未结 2 1064
北恋
北恋 2021-01-14 16:55

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

相关标签:
2条回答
  • 2021-01-14 17:37

    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.

    0 讨论(0)
  • 2021-01-14 17:54

    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

    0 讨论(0)
提交回复
热议问题