-1

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());

result expected

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
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Vinod
  • 55
  • 3
  • Can you please check this link https://stackoverflow.com/questions/49853999/convert-zoneddatetime-to-localdatetime-at-time-zone – Ranjan Aug 01 '23 at 12:25
  • 1
    `zonedDateTime.withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime()` – OH GOD SPIDERS Aug 01 '23 at 12:28
  • below is the output (7:22, expected is 18:22) 2023-08-01T18:22:09.103796200 2023-08-01T12:52:09.103796200 2023-08-01T12:52:09.103796200+05:30[Asia/Calcutta] 2023-08-01T07:22:09.103796200 – Vinod Aug 01 '23 at 12:53
  • 1
    I don't quite get why you would want to convert something to another thing and then convert that back to the original thing… That's creating (at least) 3 objects, though the first one and the third one are expected to be equal. Why not keep the first? – deHaar Aug 01 '23 at 13:06
  • Is this just an academic exercise? What is your use case? This sounds like it could be an [XY Problem](http://xyproblem.info). – WJS Aug 01 '23 at 14:23
  • actually my use case is: 1. Get local date and time from my local system 2. And get corresponding local date and time from any other country / city Or if I know UTC time with Zone ID, then convert it to that zone local date and time hope this is a valid scenario - in the above code I am converting it back to original jut to check the value is what I am looking for – Vinod Aug 02 '23 at 06:37

2 Answers2

2

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.

rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • 1
    the answer to why convert from A to B and right back again? is to check if my code is correct. I wanted to convert UTC to a given zoneId. I got where I made mistake, below line helped me ZonedDateTime zoned = nowAtUtc.atZone(ZoneOffset.UTC); thank you a lot for the clarification, it helped – Vinod Aug 02 '23 at 08:20
0

Just in addition to the answer by @rzwitzerloot…

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.

deHaar
  • 17,687
  • 10
  • 38
  • 51