Aktualna data bez daty
Dzisiaj na Facebooku ktoś zadał ciekawe pytanie: jak w JS wyświetlić aktualną datę i czas, nie używając Date
ani nie pobierając czasu z żadnego zewnętrznego źródła (nawet input[type=datetime-local]
)? Przyjrzyjmy się zatem, jak to zrobić!
Znacznik czasu Unixa
Pierwszą myślą, jaka przyszła mi do głowy, było zastąpienie Date
znacznikiem czasu Unixa. W bardzo wielu przypadkach data bywa wyrażona właśnie jako znacznik czasu Unixa. Jest to nic innego jak liczba sekund (w przypadku JS-a – milisekund), które upłynęły od północy 1 stycznia 1970 roku. Znając datę początkową i aktualną liczbę sekund, które upłynęły od niej, jesteśmy w stanie przy pomocy prostej matematyki obliczyć aktualną datę i czas.
Zatem jak się pobiera znacznik czasu w JS-ie? Przy pomocy Date.now
…
Niemniej na szczęście istnieje przynajmniej jeden mniej oficjalny sposób pobierania znacznika czasu. Swego czasu powstała specyfikacja High Resolution Time, której zadaniem było dostarczenie narzędzia do dokładnego pomiaru wydajności na stronie (poprzez obliczanie, ile milisekund upłynęło od początku do końca danego zadania). Tym samym powstało kilka metod i własności, umożliwiających dokładne określenie aktualnego czasu. Nas interesować będą dwie: performance.timeOrigin
oraz performance.now()
. performance.timeOrigin
to nic innego jak znacznik czasu w chwili wczytania danej strony internetowej. performance.now()
to z kolei liczba milisekund, jakie upłynęły od owego wczytania. Tym samym dodanie do siebie tych dwóch wartości zwróci nam aktualny znacznik czasu. Połowa pracy już za nami!
Formatowanie daty
Mając liczbę milisekund od 1 stycznia 1970 roku możemy sobie podzielić to w odpowiedni sposób, by uzyskać poszczególne elementy daty i czasu. Niemniej istnieje inny sposób: zastosowanie Intl.DateTimeFormat
. Choć według MDN formatuje on tylko obiekt Date
, to wg specyfikacji radzi sobie również ze znacznikami czasu. Tym sposobem wyświetlenie ładnie sformatowanej daty sprowadza się do:
const timestamp = Math.round( performance.timeOrigin + performance.now() );
const formatter = new Intl.DateTimeFormat( 'pl', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
} );
formatter.format( timestamp ); // czwartek, 4 kwietnia 2019, 18:06:02
Niestety, nie w każdej przeglądarce to działa (np. w Safari rzuca błędem). W pozostałych trzeba porobić odpowiednie obliczenia. Ale to już zostawię Wam do zabawy!
Komentarze
Przejdź do komentarzy bezpośrednio na Githubie.
Dawne komentarze
Ten blog wcześniej korzystał z systemu komentarzy Disqus. Jednakże pożegnaliśmy się i postanowiłem, że zaimportuję do nowej wersji stare komentarze z niego. Cóż, jego system eksportu na wiele nie pozwala…
Fajna ciekawostka. Dobra jako zagadnienie do rozmów kwalifikacyjnych! :)
A jaki jest sens zadawania takich pytań?
Wiesz Tomek, ja słyszałem, że można zrobić "Tekst do pogrubienia".bold()...
Ano, można. Jest to opisane w aneksie B specyfikacji ECMAScript, opisującym dodatkowe ficzery, które powinny być w przeglądarce → https://tc39.github.io/ecma...
Co ciekawe w Node.js też są, łącznie z obsługą komentarzy HTML-owych. V8 ewidentnie był (i wciąż jest) pisany pod uruchamianie tylko w jednym typie hostów ES.
Nie powinno być „znacznik czasu Uniksa” zamiast „znacznik czasu Unixa”? Z tego, co wiem, „x” zamienia się na „ks” w odmianie.
Obydwie formy są poprawne: https://sjp.pwn.pl/so/Unix;...
De facto wymóg wymiany "x" na "ks" istnieje wyłącznie w skrótowcach, ale ustalenie co jest skrótowcem a co nie to już całkowicie odrębny problem → https://sjp.pwn.pl/poradnia...
Senkju, prezesie — nie wiedziałem. Co nie zmienia faktu, że me oczy pozostają zrażone iksem odmienionym. :P