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 ()
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.
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.
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ą .
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;
publicfinalclassDateTimeUtil{
privateDateTimeUtil(){
super();
}
publicstaticvoidmain(final String... args){
final LocalDateTime now = LocalDateTime.now();
final LocalDateTime utc = DateTimeUtil.toUtc(now);
System.out.println("Now: " + now);
System.out.println("UTC: " + utc);
}
publicstatic 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();
}
publicstatic LocalDateTime toZone(final LocalDateTime time, final ZoneId toZone){
return DateTimeUtil.toZone(time, ZoneId.systemDefault(), toZone);
}
publicstatic LocalDateTime toUtc(final LocalDateTime time, final ZoneId fromZone){
return DateTimeUtil.toZone(time, fromZone, ZoneOffset.UTC);
}
publicstatic LocalDateTime toUtc(final LocalDateTime time){
return DateTimeUtil.toUtc(time, ZoneId.systemDefault());
}
}
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:
2019-02-2511:39// [time] original LocalDateTime without a timezone2019-02-2511:39 GMT+1// [atZone] converted to ZonedDateTime (system timezone is Madrid)2019-02-2510:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime2019-02-2510: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-2511:39// [time] original LocalDateTime without a timezone2019-02-2511:39 GMT+2// [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)2019-02-25 09:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime2019-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-2511:39// [time] original LocalDateTime without a timezone2018-08-2511:39 GMT+3// [atZone] converted to ZonedDateTime (zone is Europe/Tallinn)2018-08-25 08:39 GMT // [withZoneSameInstant] converted to UTC, still as ZonedDateTime2018-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-2803:30 GMT+3// summer time [UTC 2018-10-28 00:30]2018-10-2804:00 GMT+3// clocks are turned back 1 hour [UTC 2018-10-28 01:00]2018-10-2803:00 GMT+2// same as above [UTC 2018-10-28 01:00]2018-10-2803: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.
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 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");
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.
Odpowiedzi:
Osobiście wolę
ponieważ jest to najbardziej czytelna opcja.
źródło
Jest jeszcze prostszy sposób
źródło
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());
źródło
ldt.atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneId.of("UTC"))
podczas gdy zwięzłe nadal przekazuje wystarczające znaczenie, aby nie potrzebować zmiennej instancji strefowej.ZoneOffset.UTC
jest fajnym zamiennikiemZoneId.of("UTC")
OffsetDateTime
bardziej odpowiednia jest opcjaZonedDateTime
. Użyj:OffsetDateTime.now( ZoneOffset.UTC )
lubmyInstant.atOffset( ZoneOffset.UTC )
Skorzystaj z poniższego. Pobiera lokalną datę i godzinę i konwertuje ją na UTC przy użyciu strefy czasowej. Nie musisz tworzyć jej funkcji.
Jeśli potrzebujesz uzyskać część LocalDateTime z ZonedDateTime, możesz użyć następującego.
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(); }
źródło
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()); } }
źródło
Pytanie?
Patrząc na odpowiedzi i pytanie, wydaje się, że pytanie zostało znacznie zmodyfikowane. A więc odpowiadając na aktualne pytanie:
Strefa czasowa?
LocalDateTime
nie 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łuLocalDateTime
? 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
LocalDateTime
obiekt 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()
MetodaWynik
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:30
w strefie czasowejEurope/Tallinn
moż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
LocalDateTime
obiektu, musisz sam wiedzieć, z której strefy czasowej pochodzi, aby przekonwertować ją na UTC.źródło
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.
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 .
źródło
Spróbuj tego za pomocą tej metody.
przekonwertuj
LocalDateTime
naZonedDateTime
za 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(); }
źródło
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(); }
źródło
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); }
źródło
SimpleDateFormat
klasy. Przynajmniej nie jako pierwsza opcja. I nie bez zastrzeżeń. Dziś mamy o wiele lepszejava.time
, nowoczesne API daty i czasu Java i jegoDateTimeFormatter
.