W tym wpisie postanowiłem omówić, w jaki sposób można rozwiązać zadanie z Free Code Camp – Friendly Date Ranges. Polega ono na tym, że podany zakres dat należy tak sformatować, aby był „przyjazny” dla użytkownika tzn.:
- Powinny występować nazwy miesięcy zamiast cyfr
- Liczby porządkowe np.: 1st zamiast 1
- Jeśli zakres dat mieści się w 365 dniach, to nie powinno się wyświetlać końcowego roku
- Jeśli zakres zaczyna i kończy się w obecnym roku, to nie powinno się wyświetlać roku
- Jeśli zakres rozpoczyna się i kończy w tym samym miesiącu, to nie należy wyświetlać końcowego roku lub miesiąca
Tyle pisania już starczy.
To będzie ciało naszej funkcji
function makeFriendlyDates(arr) { //code goes here }
Dalej wewnątrz funkcji, zmienne będą przechowywać obiekty klasy Date z datą początku i konća zakresu oraz datę obecną. Natomiast obiekt friendlyRange będzie przechowywać dane dotyczące daty tj.: dzień, miesiąc, rok, czas w milisekundach.
var startDate = new Date(arr[0]), endDate = new Date(arr[1]), now = new Date(), friendlyRange = { start: {}, end: {}, range: [] };
Funkcja poniżej ma zadanie przekształcenie cyfry np.: 1 do postaci 1st.
function makeDaySuffix(date) { var day = date.getDate(); if(day === 1) return '1st'; else if(day === 2) return '2nd'; else if(day === 3) return '3rd'; return day + 'th'; }
Funkcja numToMonth() odwzorowuje numer miesiąca na nazwę tj.: 0 – January(Styczeń)
function numToMonth(num){ switch(num){ case 0: return 'January'; case 1: return 'February'; case 2: return 'March'; case 3: return 'April'; case 4: return 'May'; case 5: return 'June'; case 6: return 'July'; case 7: return 'August'; case 8: return 'September'; case 9: return 'October'; case 10: return 'November'; case 11: return 'December'; } }
Funkcja poniżej zwraca ile dni minęło między dwoma zakresami.
function checkYearDiff(start, end){ var diff = end - start; return diff / 1000 / 60 / 60 / 24; }
Funkcja formatRange() ma zadanie przygotowanie tablicy, która będzie zawierać sformatowany zakres dat.
function formatRange(start, end){ var rangeArr = [], startStr = '', endStr = '', year = { start: start.year, end: end.year }, isMoreYear = false; // check is more than year if(checkYearDiff(start.milis, end.milis) >= 365) isMoreYear = true; startStr += start.month + ' ' + start.day; if(start.year === now.getFullYear()) { if(start.month !== end.month) endStr += end.month + ' '; endStr += end.day; } else { if(!isMoreYear) startStr += ', ' + start.year; endStr += end.month + ' ' + end.day; } if(isMoreYear) { startStr += ', ' + start.year; endStr += ', ' + end.year; } rangeArr.push(startStr); if(start.milis !== end.milis) rangeArr.push(endStr); return rangeArr; }
Poniższy kod przypisuje numer dnia z suffixem, nazwę miesiąca, rok i czas w milisekundach do obiektu friendlyRange. Na samym konću zwracana jest tablica.
// set day friendlyRange.start.day = makeDaySuffix(startDate); friendlyRange.end.day = makeDaySuffix(endDate); // set month friendlyRange.start.month = numToMonth(startDate.getMonth()); friendlyRange.end.month = numToMonth(endDate.getMonth()); // set year friendlyRange.start.year = startDate.getFullYear(); friendlyRange.end.year = endDate.getFullYear(); // add time in miliseconds friendlyRange.start.milis = startDate.getTime(); friendlyRange.end.milis = endDate.getTime(); friendlyRange.range = formatRange(friendlyRange.start, friendlyRange.end); return friendlyRange.range;
To już koniec. Mam nadzieję, że wpis komuś pomoże na FCC. Jeśli ktoś ma jakieś wskazówki, jak poprawić kod, to śmiało pisać.