AngularのPipeを使って、日付を変換する

> この記事は[Angular+Firebaseでチャットアプリを作る](http://qiita.com/Yamamoto0525/items/a76ea4b3924eeb82b0f9)のエントリーです。
> 前記事：[AngularのngIfとsubmitイベントでチャットコメントを実装する](http://qiita.com/Yamamoto0525/items/a6995da3ffbb4985c5e2)
> 次記事：[Firebaseの環境構築](http://qiita.com/Yamamoto0525/items/fb23707831ff6d181544)

# この記事で行うこと

本稿では、外部ライブラリであるMoment.jsをインストールし、AngularのPipeを使って投稿した日付を日本語表記に変更します。

- [Moment.jsをインストールする](http://qiita.com/Yamamoto0525/items/afc1c23ea56ae20a1931#momentjs%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)
- [Pipeを使って、日付を変換する](http://qiita.com/Yamamoto0525/items/afc1c23ea56ae20a1931#pipe%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E6%97%A5%E4%BB%98%E3%82%92%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B)

*****
（追記：2020/6）現時点（2020年6月）での最新の内容に書き換えています。
*****


# 実装内容

## Moment.jsをインストールする

[Moment.js](https://momentjs.com/)は少し癖のあるJavaScriptの日付表示の扱いを簡単にしてくれるライブラリです。
まずはこのライブラリをプロジェクトにインストールします。

```bash
npm install moment --save
```

Commentクラスに、Moment.jsを使ってdateプロパティを追加します。

```ts:app/class/chat.ts
import * as moment from 'moment'; // 追加

export class Comment {
  user: User;
  initial: string;
  content: string;
  date: number; // 追加

  constructor(user: User, content: string) {
  	this.user = user;
  	this.initial = user.name.slice(0, 1);
  	this.content = content;
  	this.date = +moment(); // 追加
  }
}
```

`+moment()`は、現在時刻をUNIXタイムスタンプで取得するメソッドです。
ここで取得した現在時刻を、Angularに標準実装されているDatePipeを使ってビューに反映させます。

```html:app/app.component.html
  <section class="card">
    <div class="card-header">
      NgChat
    </div>
    <div class="card-body">
      <ng-container *ngFor="let comment of comments">
      <div class="media">
        <div class="media-left" *ngIf="comment.user.uid !== currentUser.uid">
          <a href="#" class="icon-rounded">{{comment.initial}}</a>
        </div>
        <div class="media-body">
          <!--DatePipeを追加-->
          <h4 class="media-heading">{{comment.user.name}} Date:{{comment.date | date:'medium'}}</h4>
          <div>{{comment.content}}</div>
        </div>
        <div class="media-right" *ngIf="comment.user.uid === currentUser.uid">
          <a href="#" class="icon-rounded">{{comment.initial}}</a>
        </div>
      </div>
      <hr>
      </ng-container>
    </div>
  </section>
```

### 実行結果

![NgChat (2).png](https://qiita-image-store.s3.amazonaws.com/0/112566/407ca0e0-b800-ead8-4736-e2c80588a9a3.png)

代表的なDatePipeのフォーマットをいくつか挙げておきます。それ以外の詳しいフォーマットは、[公式](https://angular.io/docs/ts/latest/api/common/index/DatePipe-pipe.html)を確認してください。

```ts
{{ dateObj | date }}               // output is 'Jun 15, 2015'
{{ dateObj | date:'medium' }}      // output is 'Jun 15, 2015, 9:43:11 PM'
{{ dateObj | date:'shortTime' }}   // output is '9:43 PM'
{{ dateObj | date:'mmss' }}        // output is '43:11'
```

### 2018/9 追記
検証したところ、safariでのエラーは解消されたようです。
~~AngularのDatePipeは、現時点だとsafariでエラーを起こします。ご注意ください。
参考：http://qiita.com/shun_kashiwa/items/ece352083e04737b1123~~

## Pipeを使って、日付を変換する

AngularのPipeを使って、オリジナルのpipeを作成します。
PipeはAngularJS1.xxでいうところの「filter」です。Pipeを使えば、ビューにデータを表示させる際、任意の値へ変換することができます。

例）　数字に単位をつける（100→100mm）、別の言語に翻訳する（japanese→日本語）

Angular CLIを使って、新しいPipeの雛形を作成します。

```bash
ng g pipe pipe/chat-date
```

`app.module.ts`も自動で更新され、`declarations`に`ChatDatePipe`が挿入されます。
`pipe/chat-date.ts`を開き、Moment.jsをインポートしておきます。

```ts:app/pipe/chat-date.ts
import { Pipe, PipeTransform } from '@angular/core';
import * as moment from 'moment'; // 追加

@Pipe({
  name: 'chatDate'
})
export class ChatDatePipe implements PipeTransform {

  transform(value: any, args?: any): any {
    return null;
  }

}
```
`@Pipe`デコレータで指定されている`name`プロパティは、html内に渡す時に使う名前です。
`transform()`の第1引数に元となるデータの値、第2引数には第1引数がなかった場合のデフォルト値を入れます。※デフォルト値は任意です。

Moment.jsを使って、日付表示を日本語表記に変換します。

```ts:app/pipe/chat-date.ts
export class ChatDatePipe implements PipeTransform {

  transform(date: number): string {
    moment.locale('ja');
    return moment(date).format('LLLL');
  }

}
```

```html:app/app.component.html
          <div class="media-body">
            <!--DatePipeを追加-->
            <h4 class="media-heading">{{comment.user.name}}  Date: {{comment.date | chatDate}}</h4>
            <div>{{comment.content}}</div>
          </div>
```

### 実行結果

![NgChat (3).png](https://qiita-image-store.s3.amazonaws.com/0/112566/d8c38bf4-c2ee-6227-3ef9-683da2289f83.png)

ここまでで一度クライアントサイドの実装を止め、次からはFirebaseの設定に入ります。

## ソースコード

この時点での[ソースコード](https://github.com/Yamamoto0525/NgChat/commit/3f42315a1fb7473d9bd5950b0fd6ac246a16043d)