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ć.