W większości aplikacji zachodzi potrzeba wyświetlania dat w różnych formatach. Największą popularnością na front-endowym rynku cieszy się biblioteka moment.js. W tym krótkim artykule, pokażę jak stworzyć DatePipe, który umożliwi nam wyświetlanie dat w dowolnych formatach, w oparciu o wspomnianą bibliotekę Moment.
TWORZYMY PIPE FORMATUJĄCY DATY
Zaczynamy od ściągnięcia paczki do naszej aplikacji poprzez NPM:
npm install moment --save-dev
Tworzymy plik format-date.pipe.ts i umieszczamy w nim następujący kod:
import {Pipe, PipeTransform} from '@angular/core';
import * as moment from './moment';
@Pipe({
name: 'formatDate'
})
export class FormatDatePipe implements PipeTransform {
transform(value : Date | moment.Moment | string | number, ...args: any[]) : string {
if (!value) {
return '';
}
return moment(value).format(args[0]);
}
}
Pamiętaj aby w imporcie * as moment, uwzględnić swoją ścieżkę do biblioteki. W ten oto sposób stworzyliśmy gotowego Pipe’a do wyświetlania dat.
Jak widzimy, metoda transform przyjmuje 2 parametry:
- wartość w odpowiednim typie ( string, number etc), którą będziemy chcieli sformatować
- oraz docelowy format daty, np. 'DD-MM-YYYY, HH:mm’
Celem artykułu nie jest omawianie spread operatora ( …args) oraz ogólnego schematu tworzenia Pipe’ów. Jeśli chcesz zagłębić te wątki, polecam zajrzeć do dokumentacji:
Skoro Pipe gotowy, to dodajemy go w interesującym nas module, np w app.module.ts:
declarations: [
FormatDatePipe
]
I używamy w następujący sposób, przekazując interesujący nas format w stringu:
<p> {{ date | formatDate:'HH:mm' }} </p>
<p> {{ 1479719962403 | formatDate:'dddd, DD MMM YYYY - HH:mm' }} </p>
<p> {{ 'Friday, June 24, 2016 1:42 AM' | formatDate:'MMM DD, HH:mm' }} </p>
Dostępne formaty znajdziesz w dokumentacji bliboteki momentJS.
Dla formalności napiszmy jeszcze parę testów (format-date.pipe.spec.ts):
describe('MomentPipe', () => {
let pipe = new FormatDatePipe();
const mockEpochTime : number = 1479719962403;
it("should return time in format: HH:mm", () => {
const result = pipe.transform(moment(mockEpochTime), 'HH:mm');
expect(result).toBe('09:19');
});
it("should return date in format: DD-MM-YYYY, HH:mm", () => {
const result = pipe.transform(moment(mockEpochTime), 'DD-MM-YYYY, HH:mm');
expect(result).toEqual("21-11-2016, 09:19");
});
it("should return date in format: dddd, DD MMM YYYY - HH:mm", () => {
const result = pipe.transform(moment(mockEpochTime), 'dddd, DD MMM YYYY - HH:mm');
expect(result).toEqual("Monday, 21 Nov 2016 - 09:19");
});
it("should return date in format: MMM DD, HH:mm", () => {
const result = pipe.transform(moment(mockEpochTime), 'MMM DD, HH:mm');
expect(result).toEqual("Nov 21, 09:19");
});
it('should not format empty dates', () => {
expect(pipe.transform('', 'MMMM Do YYYY')).toBe('');
expect(pipe.transform(null)).toBe('');
expect(pipe.transform(undefined)).toBe('');
expect(pipe.transform(0)).toBe('');
});
});
I Vuala, nasz format-date pipe gotowy ;), natomiast tutaj masz dostępny live example.
PODSUMOWANIE DatePipe
Na podsumowanie dodam, że powyższy przykład formatuje daty dla Twojej strefy czasowej, a jeśli chcesz aby Pipe dotyczył czasu UTC, wystarczy w środku kodu naszego pipe, podmienić return na następujący kod:
return moment.utc(value).format(args[0]);