W aplikacji JS otrzymuję znacznik czasu (eq. 1270544790922
) Z serwera (Ajax).
Na podstawie tego znacznika czasu tworzę Date
obiekt używając:
var _date = new Date();
_date.setTime(1270544790922);
Teraz _date
zdekodowany znacznik czasu w bieżącej strefie czasowej użytkownika. Nie chcę tego.
Chciałbym _ date
przekonwertować ten znacznik czasu na aktualny czas w mieście Helsinki w Europie (bez względu na aktualną strefę czasową użytkownika).
Jak mogę to zrobić?
javascript
date
timezone
warpech
źródło
źródło
Odpowiedzi:
Bazowa wartość obiektu Date jest w rzeczywistości w czasie UTC. Aby to udowodnić, należy zauważyć, że jeśli wpiszesz
new Date(0)
zobaczysz coś takiego:Wed Dec 31 1969 16:00:00 GMT-0800 (PST)
. 0 jest traktowane jako 0 w GMT, ale.toString()
metoda pokazuje czas lokalny.Ważna uwaga, UTC oznacza uniwersalny kod czasowy. Bieżący czas w 2 różnych miejscach to ten sam czas UTC, ale dane wyjściowe można sformatować inaczej.
Potrzebujemy tutaj trochę formatowania
To działa, ale ... tak naprawdę nie możesz użyć żadnej innej metody daty do swoich celów, ponieważ opisują strefę czasową użytkownika. To, czego potrzebujesz, to obiekt daty powiązany ze strefą czasową Helsinek. W tym momencie możesz użyć biblioteki innej firmy (polecam) lub zhakować obiekt daty, abyś mógł używać większości jego metod.
Opcja 1 - zewnętrzna strefa czasowa, taka jak moment
Wygląda to o wiele bardziej elegancko niż to, co zamierzamy zrobić dalej.
Opcja 2 - Zhakuj obiekt daty
Nadal myśli, że to GMT-0700 (PDT), ale jeśli nie gapisz się zbyt intensywnie, możesz pomylić to z obiektem daty, który jest przydatny do twoich celów.
Dogodnie pominąłem część. Musisz umieć zdefiniować
currentHelsinkiOffset
. Jeśli możesz użyćdate.getTimezoneOffset()
po stronie serwera lub po prostu użyć instrukcji if, aby opisać, kiedy nastąpi zmiana strefy czasowej, powinno to rozwiązać problem.Wniosek - myślę, że szczególnie w tym celu powinieneś użyć biblioteki dat, takiej jak strefa czasowa .
źródło
*60*60
zamiast tego powinno być*60000
, ponieważ getTime jest w milisekundach, a getTimezoneOffset w minutach, z czego 60000 milisekund na minutę, a nie 60 * 60 == 3600Aby uwzględnić milisekundy i strefę czasową użytkownika, użyj następujących poleceń:
źródło
Po prostu inne podejście
Twoje zdrowie!
źródło
new Date().getTimezoneOffset()
new Date(timestampStr).getTimezoneOffset()
Podejrzewam, że odpowiedź nie daje prawidłowego wyniku. W pytaniu pytający chce przekonwertować znacznik czasu z serwera na aktualny czas w Hellsinki bez względu na aktualną strefę czasową użytkownika.
Chodzi o to, że strefa czasowa użytkownika może być czymkolwiek, więc nie możemy jej ufać.
Jeśli np. sygnatura czasowa to 1270544790922 i mamy funkcję:
Kiedy nowojorczyk odwiedza stronę, alert (_helsenkiTime) drukuje:
Kiedy finalista odwiedza stronę, wyświetla alert (_helsenkiTime):
Tak więc funkcja jest prawidłowa tylko wtedy, gdy odwiedzający stronę ma docelową strefę czasową (Europa / Helsinki) na swoim komputerze, ale zawodzi w prawie każdej innej części świata. A ponieważ znacznik czasu serwera jest zwykle sygnaturą czasową UNIX, która z definicji jest podana w czasie UTC, czyli liczbie sekund, które upłynęły od Epoki Uniksa (1 stycznia 1970 00:00:00 GMT), nie możemy określić czasu letniego ani czasu innego niż czas letni na podstawie znacznika czasu.
Tak więc rozwiązaniem jest ODRZUCENIE bieżącej strefy czasowej użytkownika i zaimplementowanie sposobu obliczenia przesunięcia UTC, niezależnie od tego, czy data jest w czasie letnim, czy nie. W JavaScript nie ma natywnej metody określania historii przejścia na czas letni w innej strefie czasowej niż bieżąca strefa czasowa użytkownika. Możemy to osiągnąć najprościej za pomocą skryptu po stronie serwera, ponieważ mamy łatwy dostęp do bazy danych stref czasowych serwera z całą historią przejścia wszystkich stref czasowych.
Ale jeśli nie masz dostępu do bazy danych stref czasowych serwera (lub innego serwera) ORAZ sygnatura czasowa jest w czasie UTC, możesz uzyskać podobną funkcjonalność, zakodowując na stałe reguły czasu letniego w JavaScript.
Aby uwzględnić daty w latach 1998-2099 w Europie / Helsinkach, można skorzystać z następującej funkcji ( jsfiddled ):
Przykłady użycia:
I drukuje to, niezależnie od strefy czasowej użytkownika:
Oczywiście, jeśli możesz zwrócić znacznik czasu w postaci, w której przesunięcie (DST lub inne niż DST) jest już dodane do znacznika czasu na serwerze, nie musisz go obliczać po stronie klienta i możesz bardzo uprościć funkcję. ALE pamiętaj, aby NIE używać timezoneOffset (), ponieważ wtedy musisz poradzić sobie ze strefą czasową użytkownika i nie jest to pożądane zachowanie.
źródło
Zakładając, że otrzymujesz sygnaturę czasową według czasu helsińskiego, utworzyłbym obiekt daty ustawiony na północ 1 stycznia 1970 czasu UTC (w celu zignorowania lokalnych ustawień strefy czasowej przeglądarki). Następnie dodaj do niego wymaganą liczbę milisekund.
Uważaj później, aby zawsze pytać o wartości UTC z obiektu daty. W ten sposób użytkownicy zobaczą te same wartości dat niezależnie od ustawień lokalnych. W przeciwnym razie wartości dat zostaną przesunięte zgodnie z ustawieniami czasu lokalnego.
źródło
Możesz użyć
setUTCMilliseconds()
źródło
setUTCMilliseconds()
Metoda ustawia milisekundy dla określonej daty zgodnie z czasem uniwersalnym. [...] Jeśli określony parametr jest poza spodziewanym zakresem,setUTCMilliseconds()
podejmuje próbę odpowiedniego zaktualizowania informacji o dacie w obiekcie Date. Innymi słowy, tworzyszDate
obiekt z podaną sygnaturą czasową Uniksa w UTC.