Reputation: 57
I want to convert local date and time to UTC and then back to local date and time, I could not find solutions on internet. I used below code:
// get local date and time
LocalDateTime localDateTime = LocalDateTime.now();
// print local date time
System.out.println(localDateTime);
// get system time zone / zone id
ZoneId zoneId = ZoneId.systemDefault();
// get UTC time with zone offset
ZonedDateTime zonedDateTime = LocalDateTime.now(ZoneOffset.UTC).atZone(zoneId);
System.out.println(zonedDateTime);
// now I want to convert the UTC with timezone back to local time,
// but below code is not working
System.out.println(zonedDateTime.toLocalDateTime());
local date and time = 2023-08-01T17:15:10.832796200
zoned date and time = 2023-08-01T11:45:10.832796200+05:30[Asia/Calcutta]
local date and time after conversion = 2023-08-01T17:15:10.832796200
Upvotes: 0
Views: 1311
Reputation: 18558
Use a definite moment in time as base for coversion and zone hopping.
java.time
has such a definite moment in time: An Instant
Here's some example:
public static void main(String[] args) {
ZoneId zoneId = ZoneId.of("Asia/Calcutta");
// get a moment in time (Unix epoch) and use it as base
Instant now = Instant.now();
// get the local date and time in your zone based on the instant
LocalDateTime local = LocalDateTime.ofInstant(now, zoneId);
System.out.println(local);
// get the zoned date and time in UTC based on the instant
ZonedDateTime utc = ZonedDateTime.ofInstant(now, ZoneOffset.UTC);
System.out.println(utc);
// get the zoned date and time in your zone based on the instant
ZonedDateTime localZone = ZonedDateTime.ofInstant(now, zoneId);
System.out.println(localZone);
// extract the local date and time from it
LocalDateTime backToLocal = localZone.toLocalDateTime();
// then check for equality
if (local.equals(backToLocal)) {
System.out.println(local + " == " + backToLocal);
} else {
System.err.println(local + " != " + backToLocal);
}
}
Output (right now):
2023-08-01T20:14:39.776239
2023-08-01T14:44:39.776239Z
2023-08-01T20:14:39.776239+05:30[Asia/Calcutta]
2023-08-01T20:14:39.776239 == 2023-08-01T20:14:39.776239
I used a fix ZoneId
in order to have yours in the example.
Upvotes: 0
Reputation: 102785
ZonedDateTime zonedDateTime = LocalDateTime.now(ZoneOffset.UTC).atZone(zoneId);
This is suspect code. This code says:
What time is it right now in the UTC zone. So, here in Amsterdam it's 15:46, but if I were to run that (we're in summer time right now, amsterdam has a +2 offset), LocalDateTime.now(ZoneOffset.UTC)
gives me a local DT object with local time 13:46. It doesn't have a timezone, because.. it's local date time.
You then 'place' that time (of 13:46) in a zone. Let's say zoneId
is Europe/Amsterdam, this code gets me a time that happened 2 hours ago. It doesn't make any sense, you would never want to write this code.
What you presumably want is:
LocalDateTime nowAtUtc = LocalDateTime.now(ZoneOffset.UTC);
ZonedDateTime zoned = nowAtUtc.atZone(ZoneOffset.UTC);
ZonedDateTime inAmsterdam = zoned.atZoneSameInstant(ZoneId.of("Europe/Amsterdam"));
System.out.println(inAmsterdam.toLocalDateTime());
the above code prints the current time as per my clock here in The Netherlands.
Of course, that exact snippet is pointless - why convert from A to B and right back again? Ordinarily you'd just go LocalDateTime.now()
if you want an LDT, or if you want a ZDT, simply ZonedDateTime.now(zoneYouAreInterestedIn);
. However, I assume you asked the question because you do a bunch of stuff in between that you elided from the question.
Upvotes: 2