Podczas pisania aplikacji internetowej sensowne jest przechowywanie (po stronie serwera) wszystkich dat w bazie danych jako znaczników czasu UTC.
Byłem zdumiony, gdy zauważyłem, że natywnie nie można zrobić zbyt wiele w zakresie manipulacji strefą czasową w JavaScript.
Rozszerzyłem nieco obiekt Date. Czy ta funkcja ma sens? Zasadniczo za każdym razem, gdy wysyłam cokolwiek na serwer, będzie to znacznik czasu sformatowany za pomocą tej funkcji ...
Czy widzisz tutaj jakieś poważne problemy? A może rozwiązanie z innej strony?
Date.prototype.getUTCTime = function(){
return new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime();
}
Po prostu wydaje mi się to trochę zagmatwane. I nie jestem pewien co do wydajności.
javascript
timezone
utc
Merc
źródło
źródło
new Date().toString()
pokaże reprezentację czasową aktualnej strefy czasowej,new Date().toUTCString()
pokaże czas UTC, ale zawszenew Date().getTime()
jest to UTC , ponieważ tak definiuje się czas uniksowy: "Czas uniksowy (znany również jako czas POSIX lub czas epoki) to system do opisywania chwil w czasie, zdefiniowana jako liczba sekund, które upłynęły od 00:00:00 uniwersalnego czasu koordynowanego (UTC), czwartek, 1 stycznia 1970 r., nie licząc sekund przestępnych. "Odpowiedzi:
Daty skonstruowane w ten sposób korzystają z lokalnej strefy czasowej, przez co data utworzenia jest nieprawidłowa. Aby ustawić strefę czasową określonego obiektu daty, należy skonstruować go na podstawie ciągu dat, który zawiera strefę czasową. (Miałem problemy z uruchomieniem tego w starszej przeglądarce Androida).
Zwróć uwagę, że
getTime()
zwraca milisekundy, a nie zwykłe sekundy.W przypadku znacznika czasu UTC / Unix wystarczy:
Uwzględni to aktualne przesunięcie strefy czasowej w wyniku. W przypadku reprezentacji łańcuchowej działa odpowiedź Davida Ellisa .
W celu wyjaśnienia:
Te dane wejściowe są traktowane jako czas lokalny . Jeśli zostanie przekazany czas UTC , wyniki będą się różnić. Obserwuj (jestem teraz w GMT +02: 00, a jest 07:50):
Należy również pamiętać, że
getUTCDate()
nie można tego zastąpićgetUTCDay()
. Dzieje się tak, ponieważgetUTCDate()
zwraca dzień miesiąca ; podczas gdygetUTCDay()
zwraca dzień tygodnia .źródło
new Date()
, który tworzy nową datę na podstawie danych wejściowych UTC, ale traktuje ją jako lokalną datę / godzinę. 2) Tak, powinieneś użyćMath.floor(this.getTime() / 1000)
w tym przypadku.Możesz to również zrobić za pomocą getTimezoneOffset i getTime,
źródło
var tt = new Date('Thu Jan 01 1970 08:00:00 GMT+0800 (China Standard Time)'); (tt.getTime() - tt.getTimezoneOffset()*60*1000)/1000
. Wydaje się, żett.getTime() - tt.getTimezoneOffset()
jest to poprawneGMT+0800
.var UTCseconds = (Math.floor(x.getTime()/1000) + x.getTimezoneOffset()*60)
new Date()
zawierającego strefę czasową ... która wNajłatwiejszy sposób uzyskania czasu UTC w konwencjonalnym formacie jest następujący:
źródło
Właściwie myślę, że wartości Date w js są znacznie lepsze niż powiedzmy, że obiekty C # DateTime. Obiekty C # DateTime mają właściwość Kind, ale nie ma ścisłej podstawowej strefy czasowej jako takiej, a konwersje stref czasowych są trudne do śledzenia, jeśli konwertujesz między dwoma czasami innymi niż UTC i innymi czasami. W js wszystkie wartości Date mają bazową wartość UTC, która jest przekazywana i znana bez względu na wykonywane przez Ciebie konwersje offest lub strefy czasowej. Moją największą skargą dotyczącą obiektu Date jest liczba niezdefiniowanych zachowań, które twórcy przeglądarek zdecydowali się uwzględnić, co może zmylić ludzi atakujących daty w js metodą prób i błędów niż czytanie specyfikacji. Użycie czegoś takiego jak iso8601.js rozwiązuje to zróżnicowane zachowanie, definiując pojedynczą implementację obiektu Date.
Domyślnie specyfikacja mówi, że możesz tworzyć daty w rozszerzonym formacie daty ISO 8601, takim jak
W ten sposób możesz wywnioskować dokładny czas UTC.
Gdy chcesz przekazać wartość Date z powrotem do serwera, do którego chcesz zadzwonić
lub jeśli wolisz pracować z milisekundowym znacznikiem czasu (liczbą milisekund od 1 stycznia 1970 UTC)
ISO 8601 to standard. Nie możesz być zdezorientowany, co oznacza ciąg daty, jeśli dołączysz przesunięcie daty. Dla programisty oznacza to to, że nigdy nie musisz samodzielnie zajmować się konwersjami w czasie lokalnym . Lokalne wartości czasu istnieją wyłącznie dla korzyści użytkownika, a wartości dat są domyślnie wyświetlane w ich czasie lokalnym. Wszystkie operacje na czasie lokalnym pozwalają na wyświetlenie użytkownikowi czegoś sensownego i przekonwertowanie napisów na podstawie danych wprowadzonych przez użytkownika. Dobrą praktyką jest konwersja na UTC tak szybko, jak to możliwe, a obiekt js Date sprawia, że jest to dość trywialne.
Z drugiej strony nie ma dużego zakresu na wymuszanie strefy czasowej lub lokalizacji dla klienta (o czym jestem świadomy), co może być denerwujące w przypadku ustawień specyficznych dla witryny, ale domyślam się, że powodem tego jest to, że jest to użytkownik konfiguracja, której nie należy dotykać.
Krótko mówiąc, powodem, dla którego nie ma natywnego wsparcia dla manipulacji strefą czasową, jest to, że po prostu nie chcesz tego robić.
źródło
Zwykle nie musisz wykonywać zbyt wielu „manipulacji strefą czasową” po stronie klienta. Z reguły staram się przechowywać i pracować z datami UTC, w postaci
ticks
„ liczby milisekund od północy 1 stycznia 1970 r .”. To naprawdę upraszcza przechowywanie, sortowanie, obliczanie przesunięć, a przede wszystkim eliminuje ból głowy związany z dostosowywaniem „czasu letniego”. Oto mały kod JavaScript, którego używam.Aby uzyskać aktualny czas UTC:
Następnie generalnie potrzebujesz sformatować datę / godzinę dla użytkownika końcowego dla jego lokalnej strefy czasowej i formatu. Poniższe rozwiązuje wszystkie zawiłości formatów daty i czasu na komputerze klienckim:
A więc następujący przykład:
Zwraca następujące dane (dla moich ustawień regionalnych w języku angielskim (USA)):
źródło
getTimezoneOffset
wartość do swojejgetCurrentTimeUTC
funkcji, w rzeczywistości zwracasz inny punkt w czasie. WynikgetTime
jest już w UTC.tmLoc.getTime()
jest przesunięcie względem czasu lokalnego. Łatwo jest sprawdzić, czy masz dostęp do wszystkiego, co uruchamia JavaScript.getTime
, co wskazuje na „wartość czasu” zdefiniowaną w §15.9.5 , czyli aPrimitiveValue
, określoną w §15.9.3.3 wyraźnie jako UTC.tmLoc
przeznew Date()
, to to samo. Strefa czasowa wpłynie na ciąg znaków wyjściowychtmLoc.toString()
i podobnych elementów, ale nie wpłynie.tmLoc.getTime()
To zawsze jest tylko liczba milisekund od północy 1970-01-01 czasu UTC.//The offset is in minutes -- convert it to ms
Myślę, że to lepsze rozwiązanie
źródło
Jeśli chcesz mieć jedną linijkę , UTC Unix Timestamp można utworzyć w JavaScript jako:
Uwzględni to strefę czasową systemu. Jest to zasadniczo czas, który upłynął w sekundach od epoki.
Jak to działa:
new Date()
.unary +
przed utworzeniem obiektu, aby przekonwertować go natimestamp integer
. :+new Date()
.+new Date() / 1000
~~(+new Date())
źródło
tilde
, nietilda
(sic!). Niestety nie pozwala mi to usunąć literówki, muszę wprowadzić co najmniej 6 edycji znaków. Smooth, Stackexchange, smoothChcę wyjaśnić, że nowa Date (). GetTime () w rzeczywistości zwraca wartość UTC, więc jest to naprawdę pomocny sposób przechowywania dat i zarządzania nimi w sposób niezależny od zlokalizowanych czasów.
Innymi słowy, nie przejmuj się wszystkimi funkcjami javascript UTC. Zamiast tego po prostu użyj Date.getTime ().
Więcej informacji na temat wyjaśnienia znajduje się tutaj: Jeśli javascript "(new Date ()). GetTime ()" jest uruchamiany z 2 różnych stref czasowych.
źródło
Używam następujących:
Po zdefiniowaniu tej metody możesz:
źródło
DateTime dt = new DateTime ("2018-07-15T02:36:00+02:00");
this.getTime()
zwraca przesunięcie czasu UTC, odejmując przesunięcie lokalnej strefy czasowej, czyniąc je lokalnym, a nie UTC, więc getUTCTime zwraca przesunięcie lokalne, a nie UTC.Jestem zdumiony, jak skomplikowane stało się to pytanie.
Wszystkie są identyczne, a ich wartości całkowite all === EPOCH time: D
Nie wierz mi, sprawdź: http://www.epochconverter.com/
źródło
Ponieważ
new Date().toUTCString()
zwraca ciąg, taki jak"Wed, 11 Oct 2017 09:24:41 GMT"
możesz wyciąć ostatnie 3 znaki i przekazać pokrojony ciąg donew Date()
:źródło
EDYCJA: Poniższy kod NIE działa. Zawsze zakładałem, że new Date (). GetTime () zwróciło liczbę sekund od 1 stycznia 1970 roku W BIEŻĄCEJ STREFIE CZASOWEJ. Tak nie jest: getTime () zwraca liczbę sekund w UTC. Tak więc poniższy kod powoduje rażące przeregulowanie. Dziękuję wszystkim!]
Przede wszystkim dziękuję za fantastyczne spostrzeżenia. Wydaje mi się, że moje pytanie miało zły tytuł… powinno brzmieć „Pobierz UTC Unix Timestamp dla istniejącej daty”.
Tak więc, jeśli mam obiekt daty:
Szukałem funkcji, która powie mi „UTC Unix Timestamp”.
Ta funkcja wydaje się być prawdziwą sztuczką:
Zauważ, że to działa na „to”. Oznacza to, że mogę:
I uzyskaj liczbę sekund od 1 stycznia 1970 w czasie uniksowym. Dobrze?
To trochę szalone, dla mnie, że JavaScript przechowuje wszystko w czasie UTC, ale potem, aby uzyskać tę liczbę, muszę utworzyć nowy obiekt Date przekazujący poszczególne metody pobierające UTC, a następnie wywołać w tym celu getTime () ...
Merc.
źródło
getUTCUnixTime
staje się zły czas i JavaScript ma zapewnić prosty sposób uzyskać uniksowego znacznika czasu z pomocąDate
obiektu - przy użyciugetTime
metody. Zobacz wszystkie inne odpowiedzi.Myślę, że tego oczekujesz ...
Teraz,
źródło
Kiedy to zrobisz
To już jest znacznik czasu UTC
Testowałem na https://www.unixtimestamp.com/index.php
źródło
Korzystanie z day.js.
W wyszukiwarce:
W node.js:
Otrzymujesz znacznik czasu UTC unix bez milisekund.
źródło
Spowoduje to zwrócenie sygnatury czasowej w UTC:
źródło
new Date(new Date().toUTCString())
podaje Wed 04 Oct 2017 07:20:14 GMT + 0200 (GMT + 02:00)