Obiekt Date
JavaScript udostępnia nam konstruktor Date() który umożliwia nam w łatwy sposób przeprowadzać operacje związane z czasem.
const now = new Date();
console.dir(now);
Podstawowe metody za pomocą których możemy w łatwy sposób formatować wygląd daty (najczęściej używane):
getDate() | - zwraca dzień miesiąca (wartość z przedziału 1 - 31) |
---|---|
getDay() | - zwraca dzień tygodnia (0 dla niedzieli, 1 dla poniedziałku, 2 dla wtorku itd) |
getYear() | - zwraca liczbę reprezentującą rok (dla lat 1900 - 1999 jest to 2-cyfrowa liczba np. 99, a dla późniejszych jest to liczba 4-cyfrowa np. 2002) |
getFullYear() | - zwraca pełną liczbę reprezentującą rok (np. 1999 lub 2000) |
getHours() | - zwraca aktualną godzinę (wartość z przedziału 0 - 23) |
getMilliseconds() | - zwraca milisekundy (wartość z przedziału 0 - 999) |
getMinutes() | - zwraca minuty (wartość z przedziału 0 - 59) |
getMonth() | - zwraca aktualny miesiąc (0 - styczeń, 1 - luty itp.) |
getSeconds() | - zwraca aktualną liczbę sekund (wartość z przedziału 0 - 59) |
getTime() | - zwraca aktualny czas jako liczbę reprezentującą liczbę milisekund która upłynęła od godziny 00:00 1 stycznia 1970 roku |
Wszystkie dostępne metody znajdziesz tutaj.
Przykładowe wyświetlenie godziny może mieć postać:
const now = new Date();
console.log(now.getHours());
Wypisywanie sformatowanej daty na ekran
Skorzystajmy z powyższych metod aby wypisać sformatowaną datę:
const now = new Date();
const el = document.querySelector(".element");
const html = `
Jest teraz czas: ${now.getHours()} : ${now.getMinutes()} : ${now.getSeconds()}<br>
Dnia: ${now.getDate()} . ${now.getMonth()+1} . ${now.getFullYear()}
`
el.innerText = html
Wszystko wygląda w miarę dobrze. Jednak wciąż możemy poprawić pewne szczegóły. Wartości reprezentujące dany czas - np. minuty, sekundy lub miesiące są przedstawiane jako jednocyfrowe liczby jeżeli ich wartość jest mniejsza od 10.
Możemy to zrobić na minimum dwa sposoby:
function leadingZero(i) {
return (i < 10)? "0"+i : i;
}
//lub
function leadingZero(i) {
return `${i}`.padStart(2, "0");
}
Można też pokusić się o napisanie stosownej funkcji tagującej:
function format(parts, ...vars) {
return parts.map((part, i) => {
let v = (vars[i] !== "undefined") ? `${i}`.padStart(2, "0") : "";
return `${part}${v}`;
}).join("");
}
const now = new Date();
const el = document.querySelector(".element");
const html = format`
Jest teraz czas: ${now.getHours()} : ${now.getMinutes()} : ${now.getSeconds()}
Dnia: ${now.getDate()} . ${now.getMonth()+1} . ${now.getFullYear()}
`;
el.innerText = html
Ja pozostanę przy klasycznym podejściu...
Dzień tygodnia
Aby wypisać dzień tygodnia musimy skorzystać z metody getDay().
const now = new Date();
const element = document.querySelector(".element");
element.innerText = `Dzisiaj jest dzień tygodnia: ${now.getDay()}`; //pamiętajmy, że dni tygodnia liczone są od 0
Numer tygodni w postaci liczby nie wygląda zbyt elegancko. Aby to naprawić, możemy skorzystać z tablicy dni:
const now = new Date();
const days = ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"];
const element = document.querySelector(".element");
element.innerText = `Dzisiaj jest dzień tygodnia: ${ days[now.getDay()] }`;
Dynamiczne wypisywanie czasu
Wiedząc już jak się wypisuje aktualną datę oraz aktualny dzień tygodnia możemy napisać skrypt, który będzie to robił dynamicznie za pomocą jednej z funkcji interwałów. Teoretycznie najlepszym sposobem do zastosowania tutaj interwału:
function showTextTime() {
...
}
setInterval(() => {
showTextTime();
}, 1000);
Nie jest to jedyna możliwość. Naszym celem jest aktualizowanie czasu co sekundę, ale nie znaczy to wcale, że powinniśmy daną funkcję odpalać z taką częstotliwością. O wiele lepszym rozwiązaniem będzie odpalanie jej tak często jak to możliwe, dzięki czemu będzie mniej prawdopodobne, że nasz zegarek będzie pokazywał czas możliwie precyzyjnie.
W naszym przypadku zastosujemy requestAnimationFrame, którą używaliśmy przy animacjach canvas. Funkcja ta służy do odpalania danej funkcji możliwe często - czyli co kolejne odmalowanie strony.
<div id="elTime"></div>
<div id="elDate"></div>
const elDate = document.querySelector("#elDate");
const elTime = document.querySelector("#elTime");
function lz(i) {
return `${i}`.padStart(2, "0");
}
function showTextTime() {
const now = new Date();
const days = ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"];
const textDate = `${lz(now.getDate())} . ${lz((now.getMonth()+1))} . ${now.getFullYear()} (${days[now.getDay()]})`;
const textTime = `${lz(now.getHours())} : ${lz(now.getMinutes())} : ${lz(now.getSeconds())}`;
elDate.innerHTML = textDate;
elTime.innerHTML = textTime;
window.requestAnimationFrame(showTextTime);
}
window.requestAnimationFrame(showTextTime);
Powyższe podejście jest jednym z prostszych, ale równocześnie nie jest idealne i nie nada się do każdego zastosowania. Zrobienie zegarka na stronie - jak najbardziej. Ale zrobienie serwisu aukcyjnego bazującego na takim prostym rozwiązaniu może nas później zaboleć w sądzie...
Tekst w zależności od czasu
Poznane powyżej metody można wykorzystać do wypisywania odpowiedniej treści w zależności od aktualnego czasu. Wystarczy sprawdzić aktualny znacznik czasu (dni, godziny, minuty itp.) i w zależności od jego wartości wypisywać odpowiednią treść. Poniższy skrypt przedstawia przykładowe zastosowanie tej metody:
Ustawianie Daty i Czasu - metoda 1
W powyższych skryptach za pomocą odpowiednich metod pobieraliśmy aktualną datę i czas. JavaScript udostępnia nam także zestaw metod, za pomocą których możemy ustawiać czas i datę.
Ustawienie takie nie wpływa w żaden sposób na systemowy zegar i kalendarz - działa ono tylko w obrębie skryptu JavaScript.
Aby ustawić datę i czas możemy skorzystać z dwóch sposobów.
Pierwszym z nich polega na podaniu w nawiasach obiektu Date() poszczególnych składowych czasu. Kolejność wprowadzanych danych to: rok, miesiąc, dzień, godzina , minuta, sekunda, milisekunda, przy czym nie musimy podawać wszystkich składowych.
const time = new Date(2008, 4, 12, 15, 24, 18);
ustawi nam datę obiektu dzisiaj na:
- rok - 2008,
- miesiąc - 4 (maj) - bo liczymy od 0,
- dzień - 12,
- godzina - 15,
- minuta - 24,
- sekunda - 18
Po ustawieniu tak daty, możemy na tej zmiennej działać tak samo jak to robiliśmy powyżej.
Ustawianie Daty i Czasu - metoda 2
Drugim sposobem ustawiania czasu i daty jest zastosowanie odpowiednich metod:
setYear() - ustawia dwie ostatnie cyfry roku,
setMonth() - ustawia miesiąc,
setDate() - ustawia dzień miesiąca,
setHours() - ustawia godzinę,
setMinutes() - ustawia minuty,
setSeconds() - ustawia sekundy,
setMilliseconds() - ustawia milisekundy.
Każda metoda ustawia tylko jeden element obiektu Date. Poza tymi metodami istnieją jeszcze dodatkowe metody do ustawiania czasu.
const now = new Date();
now.setYear(2008);
now.setMonth(4);
now.setDate(12);
now.setHours(15);
now.setMinutes(24);
now.setSeconds(18);
Odliczanie
Spróbujmy napisać skrypt, który będzie odliczał dni do jakiegoś wydarzenia.
Na początku przeanalizujmy problem.
Aby zrobić takie odliczanie, musimy obliczyć różnicę między datą z przyszłości a datą teraźniejszą. Pobieramy więc oba czasy (w ms), a następnie odejmujemy od siebie. Uzyskany wynik otrzymujemy w ms.
Nas jednak interesuje liczba dni. Dzielimy więc wynik przez liczbę ms w dniu (czyli 24*60*60*1000). Dzięki temu uzyskujemy liczbę oznaczającą liczbę dni+resztę.
Aby wydobyć tą resztę, musimy od wyniku odjąć zaokrąglony wynik. Mając resztę możemy w podobny sposób obliczyć liczbę godzin, minut i sekund - wciąż posługując się podobną techniką.
const element = document.querySelector("#test8");
function lz(i) {
return `${i}`.padStart(2, "0");
}
//funkcja będzie przyjmować obiekt z danymi
//zakładam, że nie wszystkie dane zostaną przekazane
function calculateTimeDifference({year, month, day, hour = 0, minutes = 0, seconds = 0}) {
const now = new Date();
//rok, miesiąc, dzień, godzina, minuta
const importantDate = new Date(year, month-1, day, hour, minutes, seconds);
const msInADay = 24 * 60 * 60 * 1000; //1 dzień w milisekundach - to w nich przecież zwracany czas metodą getTime
const timeDifference = (importantDate.getTime() - now.getTime());
const endTime = timeDifference < 0; //czy koniec odliczania
const eDaysToDate = timeDifference / msInADay;
const daysToDate = Math.floor(eDaysToDate);
//musimy tutaj sprawdzić, czy powyższa zmienna nie jest 0,
//bo inaczej poniżej byśmy mieli dzielenie przez 0
let daysToDateFix = (daysToDate < 1)? 1 : daysToDate;
const eHoursToDate = (eDaysToDate % daysToDateFix)*24;
const hoursToDate = Math.floor(eHoursToDate);
const eMinutesToDate = (eHoursToDate - hoursToDate)*60;
const minutesToDate = Math.floor(eMinutesToDate);
const eSecondsToDate = Math.floor((eMinutesToDate - minutesToDate)*60);
const secondsToDate = Math.floor(eSecondsToDate);
return {
days : daysToDate,
hours : hoursToDate,
minutes : minutesToDate,
seconds : secondsToDate,
endTime
}
}
//funkcja korzystając z powyższej funkcji pokaże na stronie odpowiedni tekst
function showTimer(date) {
const dateParts = date.split("-");
if (dateParts.length === 1) return;
//zakładam że format daty to "2021-10-24-23-01". Ewentualnie można łatwo zmienić na inny
const [year, month, day, hour = 0, minutes = 0, seconds = 0] = dateParts;
//przekazuję do funkcji calculateTimeDifference powyższe dane
const timeDiff = calculateTimeDifference({ year, month, day, hour, minutes, seconds });
{
//a następnie wyciągam z tego co zwraca odpowiednie rzeczy
const {days, hours, minutes, seconds, endTime} = timeDiff;
if (!endTime) {
element.innerHTML = `
Do ważnej daty pozostało:
<b>${days} dni
${hours} godzin
${minutes} minut i
${lz(seconds)} sekund</b>
`;
setTimeout(() => showTimer(date), 1000);
} else {
element.innerHTML = `Ważna data upłynęła`;
}
}
}
showTimer("2023-12-13");