简体   繁体   中英

Convert UTC datetime to local datetime using java.time

I have a UTC date-time like this (a String): 2022-11-22T17:15:00

And a ZoneID like this: "America/Tijuana"

Using java.time API, I want to get the actual datetime for that zone, which is: 2022-11-22T09:15:00 (the time is 09:15 instead of 17:15)

  • ZonedDateTime.toLocalDateTime() returns: 2022-11-22T17:15
  • ZonedDateTime.toString() returns: 2022-11-22T17:15-08:00[America/Tijuana]

None of the above gives me what I'm looking for.

This is my code:

    ZoneId zonaID = ZoneId.of('America/Tijuana');
    CharSequence dateUTC = "2022-11-22T17:15:00";
    LocalDateTime dateTimeL = LocalDateTime.parse(dateUTC);
    ZonedDateTime myZDT = ZonedDateTime.now();
    ZonedDateTime myZDTFinal = myZDT.of(dateTimeL, zonaID);
    System.out.println("using toLocalDateTime: " + myZDTFinal.toLocalDateTime());
    System.out.println("using toString: " + myZDTFinal.toString());

I know that this might be a duplicated question but there's so many questions about date-times and I just haven't been able to figure out this.

Any help will be really appreciated.

You have to convert your date to UTC, then convert the convert this zone to your expected zone using withZoneSameInstant like this:

ZonedDateTime toUTCZone  = ZonedDateTime.of(dateTimeL, ZoneOffset.UTC);
ZonedDateTime myZDTFinal = toUTCZone.withZoneSameInstant(zonaID);

Output

2022-11-22T09:15-08:00[America/Tijuana]

There can be many ways to achieve the result. A simple approach would be

  1. Parse the given string into LocalDateTime .
  2. Convert it into an OffsetDateTime at UTC using LocalDateTime#atOffset .
  3. Use OffsetDateTime#atZoneSameInstant to convert the resulting OffsetDateTime into a ZonedDateTime at ZoneId.of("America/Tijuana") .
  4. Get LocalDateTime out of the resulting ZonedDateTime by using ZonedDateTime#toLocalDateTime .
  5. If required, format this LocalDateTime into the desired string.
LocalDateTime
    .parse("2022-11-22T17:15:00") // Parse the given date-time string into LocalDateTime
    .atOffset(ZoneOffset.UTC) // Convert it into a ZonedDateTime at UTC
    .atZoneSameInstant(ZoneId.of("America/Tijuana")) // Convert the result into a ZonedDateTime at another time-zome
    .toLocalDateTime() // Get the LocalDateTime out of the ZonedDateTime
    .format(DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss", Locale.ENGLISH))); // If required

Demo :

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDateTime ldtInTijuana = LocalDateTime.parse("2022-11-22T17:15:00")
                .atOffset(ZoneOffset.UTC)
                .atZoneSameInstant(ZoneId.of("America/Tijuana"))
                .toLocalDateTime();
        System.out.println(ldtInTijuana);

        // Custom format
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
        String formatted = ldtInTijuana.format(formatter);
        System.out.println(formatted);
    }
}

Output :

2022-11-22T09:15
2022-11-22T09:15:00

Note that LocalDateTime#toString removes second and fraction-of-second values if they are zero. Suppose you want to keep them ( as you have posted in your question ), you can use a DateTimeFormatter as shown above.

An alternate approach:

Alternatively, you can append Z at the end of your ISO 8601 formatted date-time string to enable Instant to parse it and then convert the Instant into a ZonedDateTime corresponding to the ZoneId.of("America/Tijuana") by using Instant#atZone . The symbol, Z refers to UTC in a date-time string.

The rest of the steps will remain the same.

Demo :

public class Main {
    public static void main(String[] args) {
        String text = "2022-11-22T17:15:00";
        text = text + "Z"; // Z refers to UTC
        Instant instant = Instant.parse(text);
        LocalDateTime ldt = instant.atZone(ZoneId.of("America/Tijuana")).toLocalDateTime();
        System.out.println(ldt);
    }
}

Output :

2022-11-22T09:15

Learn more about the modern Date-Time API from Trail: Date Time .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM