5
1

More than 3 years have passed since last update.

Moment.js の代わりとしての date-fns とは

Last updated at Posted at 2020-07-19

https://qiita.com/geeknees/items/42728ea62b4a099af462 こちらの記事で Moment.js と 代替としての Day.js または標準ライブラリの Date オブジェクトの比較を行ったのですが、date-fns というのを教えてもらったので、こちらについて今回比較したいと思います。

date-fns とは

READMEによると…

date-fns provides the most comprehensive, yet simple and consistent toolset for manipulating JavaScript dates in a browser & Node.js.

date-fns is like lodash for dates. It has 180+ functions for all occasions.

date-fnsは、ブラウザやNode.jsで最も包括的かつ、シンプルで一貫性のある、JavaScriptの日付を操作するためのツールセットを提供します。

date-fnsは日付を操作するためのlodashのようなものです。あらゆる場面で使える180以上の機能を持っています。

要点としては

補足 lodash

説明不要かもしれませんが、 lodash は _ から便利なメソッドを呼び出せるライブラリです。
https://lodash.com/

_.add(6, 4);
// => 10

で、こちらの実装方針も独自の処理をする関数をまとめて提供しています。
https://github.com/lodash/lodash/blob/master/add.js#L16

- で呼び出せるのは - で require するからですね。

// Load the full build.
var _ = require('lodash');

date-fnsの使い方

まずサンプルコード


import { format, formatDistance, formatRelative, subDays } from 'date-fns'

format(new Date(), "'Today is a' iiii")
//=> "Today is a Sunday"

formatDistance(subDays(new Date(), 3), new Date())
//=> "3 days ago"

formatRelative(subDays(new Date(), 3), new Date())
//=> "last Friday at 7:26 p.m."

format, formatDistance, formatRelative, subDays などの関数を import してそのまま使うだけですね。

基本的な処理(かなり便利に)はできそうですね。

getterの便利なヘルパーも多く実装されています。
- https://date-fns.org/v2.15.0/docs/getSeconds
- https://date-fns.org/v2.15.0/docs/isFriday

date-fns with Time Zones

最後に Time Zones を見てみましょう。ドキュメントになぜ Time Zone の扱いにおいて難しい部分をわかりやすく説明してくれています。

The difficulty comes when working with another time zone's local time, other than the current system's, like showing the local time of an event in LA at 8pm PST on a Node server in Europe or a user's machine set to EST.

難しいのは、現在のシステム以外のタイムゾーンのローカルタイムを扱う場合です。例えば、ヨーロッパのノードサーバやユーザのマシンがESTに設定されている場合に、ロスのイベントのローカルタイムを20時PSTで表示するような場合です。

サンプルコードは下記のとおりです。わかりやすいですね。


const { zonedTimeToUtc, utcToZonedTime, format } = require('date-fns-timezone')

// Set the date to "2018-09-01T16:01:36.386Z"
const utcDate = zonedTimeToUtc('2018-09-01 18:01:36.386', 'Europe/Berlin')

// Obtain a Date instance that will render the equivalent Berlin time for the UTC date 
const date = new Date('2018-09-01Z16:01:36.386Z')
const timeZone = 'Europe/Berlin'
const zonedDate = utcToZonedTime(date, timeZone)
// zonedDate could be used to initialize a date picker or display the formatted local date/time

// Set the output to "1.9.2018 18:01:36.386 GMT+02:00 (CEST)"
const pattern = 'D.M.YYYY HH:mm:ss.SSS [GMT]Z (z)'
const output = format(zonedDate, pattern, { timeZone })

date-fns-timezone は別パッケージとして管理されています。
https://github.com/prantlf/date-fns-timezone

date-fns-tz も互換があります。ドキュメントのサンプルコードは date-fns-timezone を使っていますが、 date-fns-tz のほうが直近のコミットもあり、date-fns v2.0.0 の対応を明記されているので良いかもしれません。
https://github.com/marnusw/date-fns-tz

その上で実際のタイムゾーンの情報は timezone-support が活用されています。
https://github.com/prantlf/timezone-support

実際のデータは下記らへんですね。
https://github.com/prantlf/timezone-support/blob/master/util/data/meta.json
https://github.com/prantlf/timezone-support/blob/master/util/data/unpacked.json

date-fns を使うかどうかの個人的な見解

  • date-fns は薄いし、タイムゾーンの対応も拡張できるとても便利なライブラリだと思います
  • モダンなフロントエンド開発においては、あえて Moment.js を使う理由は見当たりません
  • 一方で、標準ライブラリでも対応できる範囲であれば、後からでも入れられるので無理して最初から入れなくても良いかもしれません
    • タイムゾーンを扱う場合や曜日の判定を多く実装するのであれば導入を検討していいでしょう
  • ただし、 node や deno などサーバーサイドで用いる場合は、タイムスタンプのバリデーションなどを簡易に書けるので入れておくほうが良い気がします

まとめると……依存関係が複数のメンテナーに分散しているのは気になりますが、今っぽい感じ(npmっぽい)とも言えます。クライアントサイドで使う場合は、用法用量によるとおもうので判断が分かれる感じもしますが、node や deno などサーバーサイドで日付関連の処理を多く行うのであれば、かなり導入を検討しても良さそうです。

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1