Vue.js filters – formatowanie daty

Filtry w Vue.js są jak helper’y czy utils’y w C#. Takie pomocnicze metody, które przydają się w wielu miejscach w aplikacji i pozwalają uniknąć duplikowania kodu. Podstawowe informacje na ich temat można przeczytać tutaj lub w formie tutoriala na youtube.
Pierwszy filtr, który zaimplementowałem w aplikacji Dogevents wiązał się z wyświetlaniem daty wydarzenia. Każde wydarzenie składa się z dwóch pól typu data/czas określających jego początek oraz koniec:

{
"start_time": "2017-05-06T14:30:00+0200",
"end_time": "2017-05-06T19:30:00+0200",
}

Przedstawiony format choć jest jak najbardziej prawidłowy w kontekście wymiany, przechowywania danych o tyle jego czytelność jest niska – nie jest „user friendly” 🙂

Prócz bardziej przyjaznego wyświetlania tych informacji chciałem uzyskać jeszcze kilka dodatkowych efektów:

  • Jeśli wydarzenie odbywa się w jednym dniu wyświetlić tylko raz datę i godzinę rozpoczęcia + godzinę zakończenia, np. 2017-02-04 10:00 – 14:00
  • Jeśli wydarzenie trwa więcej niż jeden dzień i nie jest na przełomie miesiąca wyświetlić jego datę jako 5 – 8 Maj 2017
Wyświetlanie daty wydarzenia z użyciem filtra 
Działający przykład udostępniłem na JSFiddle

Na początek wywołanie filtra toEventDate z poziomu szablonu:

<div id="app">
<p>{{ { start_time: start_time, end_time: end_time } | toEventDate}}</p>
</div>

Wykonuję tu jedną dodatkową rzecz – opakowanie w obiekt dwóch właściwości start_time, end_time tak aby móc przekazać je jako jeden parametr do funkcji filtra. Następnie rejestracja globalnego filtra:

Vue.filter('toEventDate', function(eventDate){
//some logic here ...
}

I ostateczna funkcjonalność:

Vue.filter('toEventDate', function(eventDate) {
let startTime = new Date(eventDate.start_time);
let endTime = new Date(eventDate.end_time);
let locale = 'en-EN';
let dateFormatOptions = {
day: 'numeric',
month: 'long'
};
let timeFormatOptions = {
hour: 'numeric',
minute: 'numeric'
};

if (startTime.toLocaleDateString() === endTime.toLocaleDateString())
return startTime.toLocaleDateString(locale, dateFormatOptions) + ' ' + startTime.toLocaleTimeString(locale, timeFormatOptions) + ' - ' + endTime.toLocaleTimeString(locale, timeFormatOptions);

if (eventDate.start_time.substring(0, 7) == eventDate.end_time.substring(0, 7))
return startTime.getDate() + ' - ' + endTime.getDate() + ' ' + startTime.toLocaleDateString(locale, {
month: 'long'
})

return startTime.toLocaleDateString(locale, dateFormatOptions) + ' - ' + endTime.toLocaleDateString(locale, dateFormatOptions)
});