ZonedDateTime - jak pobrać czas z konkretnej ZoneId posiadając inną

ZonedDateTime - jak pobrać czas z konkretnej ZoneId posiadając inną
Burdzi0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Futurama
  • Postów: 887
0

Hejka,

Próbowałem ogarnąć tę pierdołę i chyba jest ze mną coś nie tak.
Serwer zwraca mi datę UTC (2h mniejszą niż Europe/Warsaw).
Chciałbym zwracać zawsze ZonedDateTime dla Europe/Warsaw, bez względu czy na serwerze jest zwracana by default data UTC czy Europe/Warsaw (czy inna).

Próbowałem już:

Kopiuj
private final ZoneId zoneId = ZoneId.of("Europe/Warsaw");
return ZonedDateTime.now(zoneId);

czy

Kopiuj
final ZoneId zone = ZoneId.of("Europe/Warsaw");
return ZonedDateTime.of(LocalDateTime.now(), zone);

Jakieś pomysły?

Charles_Ray
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 1912
0

Tzn. co dokładnie zwraca serwer? Czas bez strefy czasowej? A Ty chcesz wziąć ten sam punkt w czasie zwrócić jako Europe/Warsaw? Pamiętaj, że te 2h różnicy jest zmienne w czasie.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
0

Weź sobie Instant.now() i dostaniesz epoch i z niego zrób sobie obiekt w odpowiedniej zonie.

Burdzi0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Futurama
  • Postów: 887
0

@Charles_Ray: Wyraziłem się niejasno - czas systemowy serwera jest różny. Na jednym serwie jest czas UTC, na innym lokalny.

@Shalom

Weź sobie Instant.now() i dostaniesz epoch i z niego zrób sobie obiekt w odpowiedniej zonie.

Dla kodu

Kopiuj
private final ZoneId zone = ZoneId.of(EUROPE_WARSAW);

    public ZonedDateTime getTime() {
        return Instant.now().atZone(zone);
    }

Wynik z jshell:

2020-04-06T08:09:45.506234+02:00[Europe/Warsaw]

Wynik zapytania do mojej aplikacji na serwerze, gdzie jest UTC:

"time":"2020-04-06T06:09:37.68326+02:00"

Lokalnie odpalone - otrzymuję:

"time":"2020-04-06T06:09:37.68326+02:00"

Chyba nie mówiłem - wykorzystuję Spring Boot

Co robię źle?

PI
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2787
3

Nie wiem czy do końca rozumiem czemu masz problem i co dokładnie chcesz osiągnąć, ale czas i strefy czasowe to zawsze trudny temat. Proponuję cofnąć się do początku:

Instant.now() zwraca Ci konkretny punkt czasowy - 8:00 u kolesia w Londynie i 10:00 w Warszawie to ten sam punkt czasowy. Instanty dobrze jest wykorzystywać jeśli chcemy operować na interwałach
Jeśli mówimy o zdarzeniach, które mamy zaplanowane o jakiejś godzinie, np jutro o 10 mam fryzjera, to mówimy już o konkretnej godzinie w danej sferze czasowej - i tu lepiej LocalDateTime używać.
Myślę też, że serwer powinien zawsze zwracać czas w UTC i w ogóle nie mieć informacji o sferze czasowej klienta (frontu). Informację tę powinien mieć frontend, i to on powinien dostosowywać UTC do czasu lokalnego danego użytkownika.

Nie wiem czy ten post coś pomoże, ale powodzenia ;)

Burdzi0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Futurama
  • Postów: 887
0

Załóżmy, że mam aplikację Spring Boot i mam endpoint, który zwraca stopkę czasową.
Mam dwa środowiska (np. A i B).
W Polsce jest godzina 12:00.
Na środowisku A czas jaki mi zwraca ZonedDateTime.now() to czas UTC (godzina 10:00).
Na środowisku B czas jaki mi zwraca ZonedDateTime.now() to czas Europe/Warsaw (godzina 12:00).

Co chcę osiągnąć?
Bez względu na to gdzie zrobię deploy chcę otrzymywać czas dla strefy Europe/Warsaw (tj. 12:00 podążając przykładem wyżej), bez konieczności tworzenia dwóch odrębnych konfiguracji.

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
0

A jakiego longa zwraca ci Instant.now() w tych środowiskach? Bo powinien zwracać ci dokładnie tą samą wartość, epoch UTC.

Burdzi0
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Futurama
  • Postów: 887
0

Instant z serwera:

Kopiuj
"2020-04-10T15:28:19.785750Z"

Lokalnie:

Kopiuj
"2020-04-10T17:30:51.286602Z"

Faktyczna godzina to 19:30 xD już w ogóle się wszystko wykrzaczyło :P serwer nie ma updatu na przesunięcie czasu, pewnie będę musiał ręcznie coś ogarniać. W każdym razie pytanie aktualne - bez względu na strefę, jak wyświetlić czas w polszy?

Shalom
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Space: the final frontier
  • Postów: 26433
0

Coś takiego: Instant.now().atZone(ZoneId.of("UTC") powinno dać taki sam wynik gdziekolwiek tego nie odpalisz.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.