Konwertuj LocalDateTime na LocalDateTime w UTC

86

Konwertuj LocalDateTime na LocalDateTime w UTC.

LocalDateTime convertToUtc(LocalDateTime date) {

    //do conversion

}

Szukałem w sieci. Ale nie dostałem rozwiązania

Sarika.S
źródło
4
Czy znalazłeś javadoc dla LocalDateTime? Mówi: „Ta klasa nie przechowuje ani nie reprezentuje strefy czasowej. Zamiast tego jest opisem daty używanym w przypadku urodzin, połączonym z czasem lokalnym wyświetlanym na zegarze ściennym. Nie może przedstawiać ani chwili na oś czasu bez dodatkowych informacji, takich jak przesunięcie lub strefa czasowa ”.
aro_tech
1
Twoje pytanie nie ma sensu - powinieneś wyjaśnić kontekst tej metody i co próbujesz osiągnąć. Wygląda na to, że masz fundamentalne niezrozumienie tego, co reprezentują różne klasy API.
assylias
3
Jeśli zależy Ci na strefach czasowych, musisz użyć ZonedDateTime, który ma metody konwersji między strefami czasowymi withZoneSameLocal () i withZoneSameInstant ()
JodaStephen
Ya. Zrozumiałem. Dzięki
Sarika.S

Odpowiedzi:

104

Osobiście wolę

LocalDateTime.now(ZoneOffset.UTC);

ponieważ jest to najbardziej czytelna opcja.

slorinc
źródło
26
Czy to nie tworzy nowego czasu (teraz)? Pierwotne pytanie dotyczyło konwersji znanego czasu na UTC
Evvo,
Jak przeliczylibyśmy z LocalDateTime na UTC -7: 00
Ashok kumar Ganesan
74

Jest jeszcze prostszy sposób

LocalDateTime.now(Clock.systemUTC())
Leon Radley
źródło
26
Fajnie, ale nie odpowiada na pierwotne pytanie.
eirirlar
3
Ta odpowiedź konwertuje datę UTC na LocalDate. Pierwotne pytanie dotyczyło tego, jak przekonwertować LocalDate na datę UTC.
Cypress Frankenfeld
Jak przeliczylibyśmy z LocalDateTime na UTC -7: 00
Ashok kumar Ganesan
64

LocalDateTime nie zawiera informacji o strefie. ZonedDatetime tak.

Jeśli chcesz przekonwertować LocalDateTime na UTC, musisz zawinąć pięścią ZonedDateTime.

Możesz konwertować jak poniżej.

LocalDateTime ldt = LocalDateTime.now();
System.out.println(ldt.toLocalTime());

ZonedDateTime ldtZoned = ldt.atZone(ZoneId.systemDefault());

ZonedDateTime utcZoned = ldtZoned.withZoneSameInstant(ZoneId.of("UTC"));

System.out.println(utcZoned.toLocalTime());
Fatih Arslan
źródło
2
To jest poprawne, choć nie jest technicznie opakowane. ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))podczas gdy zwięzłe nadal przekazuje wystarczające znaczenie, aby nie potrzebować zmiennej instancji strefowej.
Brett Ryan
22
ZoneOffset.UTCjest fajnym zamiennikiemZoneI‌​d.of("UTC")
ycomp
2
W przypadku UTC OffsetDateTimebardziej odpowiednia jest opcja ZonedDateTime. Użyj: OffsetDateTime.now( ZoneOffset.UTC )lubmyInstant.atOffset( ZoneOffset.UTC )
Basil Bourque
15

Skorzystaj z poniższego. Pobiera lokalną datę i godzinę i konwertuje ją na UTC przy użyciu strefy czasowej. Nie musisz tworzyć jej funkcji.

ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);
System.out.println(nowUTC.toString());

Jeśli potrzebujesz uzyskać część LocalDateTime z ZonedDateTime, możesz użyć następującego.

nowUTC.toLocalDateTime();

Oto statyczna metoda, której używam w mojej aplikacji, aby wstawić czas UTC w mysql, ponieważ nie mogę dodać domyślnej wartości UTC_TIMESTAMP do kolumny z datą i godziną .

public static LocalDateTime getLocalDateTimeInUTC(){
    ZonedDateTime nowUTC = ZonedDateTime.now(ZoneOffset.UTC);

    return nowUTC.toLocalDateTime();
}
patelb
źródło
14

Oto prosta mała klasa narzędziowa, której można użyć do konwersji lokalnych dat ze strefy na strefę, w tym metoda narzędzia bezpośrednio do konwersji lokalnej daty i czasu z bieżącej strefy na UTC (z główną metodą, aby można było ją uruchomić i zobaczyć wyniki prostego testu):

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;

public final class DateTimeUtil {
    private DateTimeUtil() {
        super();
    }

    public static void main(final String... args) {
        final LocalDateTime now = LocalDateTime.now();
        final LocalDateTime utc = DateTimeUtil.toUtc(now);

        System.out.println("Now: " + now);
        System.out.println("UTC: " + utc);
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId fromZone, final ZoneId toZone) {
        final ZonedDateTime zonedtime = time.atZone(fromZone);
        final ZonedDateTime converted = zonedtime.withZoneSameInstant(toZone);
        return converted.toLocalDateTime();
    }

    public static LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone) {
        return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
    }

    public static LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone) {
        return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
    }

    public static LocalDateTime toUtc(final LocalDateTime time) {
        return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
    }
}
ManoDestra
źródło
Dodaj także: final LocalDateTime backToLocal = DateTimeUtil.toZone (utc, ZoneOffset.UTC, ZoneId.systemDefault ()); System.out.println ("Powrót do lokalnego:" + backToLocal);
rjdkolb
9

Pytanie?

Patrząc na odpowiedzi i pytanie, wydaje się, że pytanie zostało znacznie zmodyfikowane. A więc odpowiadając na aktualne pytanie:

Konwertuj LocalDateTime na LocalDateTime w UTC.

Strefa czasowa?

LocalDateTimenie przechowuje żadnych informacji o strefie czasowej, po prostu przechowuje wartości roku, miesiąca, dnia, godziny, minuty, sekundy i mniejszych jednostek. Tak więc ważne pytanie brzmi: jaka jest strefa czasowa oryginału LocalDateTime? Równie dobrze może to być już UTC, dlatego nie trzeba dokonywać żadnej konwersji.

Domyślna strefa czasowa systemu

Biorąc pod uwagę, że i tak zadałeś to pytanie, prawdopodobnie miałeś na myśli, że oryginalny czas jest w domyślnej strefie czasowej systemu i chcesz go przekonwertować na UTC. Ponieważ zwykle LocalDateTimeobiekt jest tworzony za pomocą polecenia, LocalDateTime.now()które zwraca bieżący czas w domyślnej strefie czasowej systemu. W tym przypadku konwersja wyglądałaby następująco:

LocalDateTime convertToUtc(LocalDateTime time) {
    return time.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

Przykład procesu konwersji:

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+1 // [atZone] converted to ZonedDateTime (system timezone is Madrid)
2019-02-25 10:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 10:39 // [toLocalDateTime] losing the timezone information

Jawna strefa czasowa

W każdym innym przypadku, gdy wyraźnie określisz strefę czasową czasu konwersji, konwersja będzie wyglądać następująco:

LocalDateTime convertToUtc(LocalDateTime time, ZoneId zone) {
    return time.atZone(zone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
}

Przykład procesu konwersji:

2019-02-25 11:39 // [time] original LocalDateTime without a timezone
2019-02-25 11:39 GMT+2 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2019-02-25 09:39 // [toLocalDateTime] losing the timezone information

atZone()Metoda

Wynik atZone()metody zależy od czasu podanego jako jej argument, ponieważ uwzględnia ona wszystkie reguły strefy czasowej, w tym czas letni (DST). W przykładach był to 25 lutego, w Europie oznacza to czas zimowy (bez czasu letniego).

Gdybyśmy mieli użyć innej daty, powiedzmy 25 sierpnia ubiegłego roku, wynik byłby inny, biorąc pod uwagę czas letni:

2018-08-25 11:39 // [time] original LocalDateTime without a timezone
2018-08-25 11:39 GMT+3 // [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)
2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime
2018-08-25 08:39 // [toLocalDateTime] losing the timezone information

Czas GMT się nie zmienia. Dlatego przesunięcia w innych strefach czasowych są dostosowywane. W tym przykładzie czas letni w Estonii to GMT + 3, a czas zimowy GMT + 2.

Ponadto, jeśli określisz czas w ramach przejścia zmiany zegarów wstecz o jedną godzinę. Np. 28 października 2018 03:30 dla Estonii, może to oznaczać dwa różne czasy:

2018-10-28 03:30 GMT+3 // summer time [UTC 2018-10-28 00:30]
2018-10-28 04:00 GMT+3 // clocks are turned back 1 hour [UTC 2018-10-28 01:00]
2018-10-28 03:00 GMT+2 // same as above [UTC 2018-10-28 01:00]
2018-10-28 03:30 GMT+2 // winter time [UTC 2018-10-28 01:30]

Bez ręcznego określania przesunięcia (GMT + 2 lub GMT + 3), czas 03:30w strefie czasowej Europe/Tallinnmoże oznaczać dwa różne czasy UTC i dwa różne przesunięcia.

Podsumowanie

Jak widać, wynik końcowy zależy od strefy czasowej czasu podanego jako argument. Ponieważ strefy czasowej nie można wyodrębnić z LocalDateTimeobiektu, musisz sam wiedzieć, z której strefy czasowej pochodzi, aby przekonwertować ją na UTC.

anddero
źródło
1
dzięki za informację o LocalDateTime nie przechowuje żadnych informacji o strefie czasowej! LocalDateTime does not store any information about the time-zone, it just basically holds the values of year, month, day, hour, minute, second, and smaller units.
LiuWenbin_NO.
5

tldr: po prostu nie da się tego zrobić; jeśli próbujesz to zrobić, otrzymujesz błąd LocalDateTime .

Powodem jest to, że LocalDateTime nie rejestruje strefy czasowej po utworzeniu instancji. Nie można przekonwertować daty i godziny bez strefy czasowej na inną datę i godzinę na podstawie określonej strefy czasowej.

W rzeczywistości, LocalDateTime.now () nigdy nie powinna być wywoływana w kodzie produkcyjnym, chyba że celem jest uzyskanie losowych wyników. Podczas konstruowania instancji LocalDateTime w ten sposób, ta instancja zawiera TYLKO datę i godzinę na podstawie strefy czasowej bieżącego serwera, co oznacza, że ​​ten fragment kodu wygeneruje inny wynik, jeśli działa serwer z inną konfiguracją strefy czasowej.

LocalDateTime może uprościć obliczanie dat. Jeśli chcesz mieć prawdziwy, uniwersalny czas danych, użyj ZonedDateTime lub OffsetDateTime: https://docs.oracle.com/javase/8/docs/api/java/time/OffsetDateTime.html .

Andrew Feng
źródło
LocalDateTime nie rejestruje strefy czasowej, ale możesz mieć tę wiedzę z innego miejsca i dodać te informacje do swoich LocalDateTimes przed konwersją.
Tristan
1

Spróbuj tego za pomocą tej metody.

przekonwertuj LocalDateTimena ZonedDateTimeza pomocą metody of i podaj domyślną strefę czasową systemu lub możesz użyć ZoneId swojej strefy, na przykładZoneId.of("Australia/Sydney");

LocalDateTime convertToUtc(LocalDateTime dateTime) {
  ZonedDateTime dateTimeInMyZone = ZonedDateTime.
                                        of(dateTime, ZoneId.systemDefault());

  return dateTimeInMyZone
                  .withZoneSameInstant(ZoneOffset.UTC)
                  .toLocalDateTime();
  
}

Aby przywrócić lokalną datę i godzinę strefy, użyj:

LocalDateTime convertFromUtc(LocalDateTime utcDateTime){
    return ZonedDateTime.
            of(utcDateTime, ZoneId.of("UTC"))
            .toOffsetDateTime()
            .atZoneSameInstant(ZoneId.systemDefault())
            .toLocalDateTime();
}
Habeeb Okunade
źródło
-1

możesz zaimplementować pomocnika wykonującego coś takiego:

public static LocalDateTime convertUTCFRtoUTCZ(LocalDateTime dateTime) {
    ZoneId fr = ZoneId.of("Europe/Paris");
    ZoneId utcZ = ZoneId.of("Z");
    ZonedDateTime frZonedTime = ZonedDateTime.of(dateTime, fr);
    ZonedDateTime utcZonedTime = frZonedTime.withZoneSameInstant(utcZ);
    return utcZonedTime.toLocalDateTime();
}
ddinh
źródło
UTC fr do UTC Z? nic nie znaczy. UTC = Z, UTC <> fr
Tristan
-2
public static String convertFromGmtToLocal(String gmtDtStr, String dtFormat, TimeZone lclTimeZone) throws Exception{
        if (gmtDtStr == null || gmtDtStr.trim().equals("")) return null;
        SimpleDateFormat format = new SimpleDateFormat(dtFormat);
        format.setTimeZone(getGMTTimeZone());
        Date dt = format.parse(gmtDtStr);
        format.setTimeZone(lclTimeZone);
        return

format.format (dt); }

Ganesh
źródło
1
Proszę, nie uczcie młodych, aby korzystali z dawno przestarzałej i notorycznie kłopotliwej SimpleDateFormatklasy. Przynajmniej nie jako pierwsza opcja. I nie bez zastrzeżeń. Dziś mamy o wiele lepsze java.time, nowoczesne API daty i czasu Java i jego DateTimeFormatter.
Ole VV