日付時刻操作ライブラリをmomentからdayjsへ乗り換えた
日付時刻操作ライブラリをmomentからdayjsへ乗り換えた:
この記事は「DeNAその2 Advent Calendar 2018」16日目の記事です。
JavaScriptの日付時刻操作は罠が多く、コードのメンテナンスも行いにくいため、
GitHub Star数が4万に迫っていて、安定感のあるmomentをこれまで採用してきました。
参考: https://qiita.com/labocho/items/5fbaa0491b67221419b4
しかし、momentはファイルサイズが大きく、jsのバンドルサイズが肥大化する原因にもなっていました。
そんな時、Vue Fes Japan 2018の公演の中だったり、有識者の記事の中だったりで、momentではない他の日付時刻操作ライブラリを採用しているケースを知り、今回調べてみることにしました。
以下は検討するきっかけとなった資料です。
調べるにあたって重視したのは以下の2点です。
私たちのサービスにおいて、momentが行なっていた処理は以下の3つです。
サンプルコードの通り、momentがtimestampを受け取って日付時刻を操作しています。
❶. 日付時刻をフォーマットする
❷. 日付の加算と減算を計算する
❸. 2つの日付の日数を計算する
検討対象にしたライブラリは、「moment」と「dayjs」「date-fns」「luxon」です。GitHub Starが多く、メンテナンスが継続的に行われているライブラリをピックアップしてみました。
luxonについては、momentと同じリポジトリで開発されており、興味もあって検討対象に入れてみました。
npmのダウンロード数を比較できるnpmtrendsによると、momentはまだまだ圧倒的に支持されており、次いでdate-fnsが徐々にシェアを伸ばしている様子。
dayjsとluxon頑張れ!というような状態です。
画像元はこちらです。
https://www.npmtrends.com/date-fns-vs-dayjs-vs-luxon-vs-moment
上述のnpmのダウンロード数では、dayjsよりもdate-fnsが上回っていましたが、GitHub Starはdayjsの方が上回っています。
dayjsは今年の4月に生まれたばかりなので、これからさらに伸びていくことに期待です。
Documentについては、どのライブラリもよくまとめられていました。
その中でも、date-fnsは、欲しい情報がすぐに見つけられて好感を持ちました。
例えば、日付を加算するメソッドを探そうと
URL: https://date-fns.org/docs/Getting-Started
ライブラリごとの情報は以下の通りです。
(2018/12/10 00:03時点)
GitHub: https://github.com/moment/moment
Document: https://momentjs.com
GitHub Star: 39,459 / Latest commit: Oct 31, 2018 / created: Mar 1, 2011
GitHub: https://github.com/iamkun/dayjs
Document: https://github.com/iamkun/dayjs/blob/master/docs/ja/README-ja.md
GitHub Star: 16,821 / Latest commit: Nov 20, 2018 / created: Apr 10, 2018
GitHub: https://github.com/date-fns/date-fns
Document: https://date-fns.org
GitHub Star: 15,312 / Latest commit: Nov 14, 2018 / created: Oct 6, 2014
GitHub: https://github.com/moment/luxon
Document: https://moment.github.io/luxon
GitHub Star: 7290 / Latest commit: Nov 30, 2018 / created: Nov 30, 2015
各ライブラリのサンプルコードを記載していきます。
処理は前提で記載した以下3つの処理を各ライブラリごとに記載しています。
momentは、前提に記載しているので省略します。
moment経験者は学習要らずかもしれません。
❶. 日付時刻をフォーマットする
❷. 日付の加算と減算を計算する
❸. 2つの日付の日数を計算する
他のライブラリは、メソッドチェーンで頑張っていくのに対して、date-fnsはコードがシンプルに書けて使いやすかったです。
❶. 日付時刻をフォーマットする
❷. 日付の加算と減算を計算する
❸. 2つの日付の日数を計算する
明示的なAPIがluxonの1つの特徴です。moment, dayjs, date-fnsは、「timestamp」「ISO8601フォーマットの文字列」「Dateオブジェクト」等をAPIに渡せば日付時刻操作を行うことができます。
一方luxonは、日付時刻の形式ごとにAPIが分けられているので、日付時刻のデータを厳密に管理したい人にとっては良いのかもしれません。
参考: https://qiita.com/jnst/items/545d9a7a5a95e190fbf5#-なぜ-luxon-がつくられたか
それでは、サンプルコードです。
❶. 日付時刻をフォーマットする
❷. 日付の加算と減算を計算する
❸. 2つの日付の日数を計算する
上記サンプルコードをNuxt.js上に書き、それをanalyzeしてファイルサイズを確認しました。
以下にリポジトリを公開しています。
GitHub: https://github.com/yagisuke/jikan-libraries
ファイルサイズが軽量なものから並べています。
dayjsとdate-fnsはmomentよりもだいぶ軽量だったので好印象でした。
luxonはmomentよりも重いようです。
「moment」「dayjs」「date-fns」「luxon」をそれぞれみてきました。
比較するのって楽しいですね
そして、比較した結果、今回は
採用した理由としては、以下の通りです。
momentユーザーの方は、この機会にぜひ
以上、お付き合いいただきありがとうございました。
この記事は「DeNAその2 Advent Calendar 2018」16日目の記事です。
背景
JavaScriptの日付時刻操作は罠が多く、コードのメンテナンスも行いにくいため、GitHub Star数が4万に迫っていて、安定感のあるmomentをこれまで採用してきました。
参考: https://qiita.com/labocho/items/5fbaa0491b67221419b4
しかし、momentはファイルサイズが大きく、jsのバンドルサイズが肥大化する原因にもなっていました。
そんな時、Vue Fes Japan 2018の公演の中だったり、有識者の記事の中だったりで、momentではない他の日付時刻操作ライブラリを採用しているケースを知り、今回調べてみることにしました。
以下は検討するきっかけとなった資料です。
前提
調べるにあたって重視したのは以下の2点です。2について補足します。
- momentよりもファイルサイズが軽量のもの
- momentで行なっている日付時刻操作を代替できるもの
私たちのサービスにおいて、momentが行なっていた処理は以下の3つです。
サンプルコードの通り、momentがtimestampを受け取って日付時刻を操作しています。
❶. 日付時刻をフォーマットする
import moment from 'moment' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 moment(timestamp).format('YYYY/MM/DD HH:mm:ss') > 2018/12/16 07:00:00
import moment from 'moment' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 moment(timestamp).add(3, 'days').format('YYYY/MM/DD') > 2018/12/19 moment(timestamp).add(-3, 'days').format('YYYY/MM/DD') > 2018/12/13
import moment from 'moment' const timestamp1 = 1544911200 * 1000 // 2018/12/16 07:00:00 const timestamp2 = 1549663200 * 1000 // 2019/02/09 07:00:00 moment(timestamp1).diff(timestamp2, 'days') > -55 moment(timestamp2).diff(timestamp1, 'days') > 55
検討対象とその情報について
検討対象にしたライブラリは、「moment」と「dayjs」「date-fns」「luxon」です。GitHub Starが多く、メンテナンスが継続的に行われているライブラリをピックアップしてみました。luxonについては、momentと同じリポジトリで開発されており、興味もあって検討対象に入れてみました。
npmのダウンロード数から見る
npmのダウンロード数を比較できるnpmtrendsによると、momentはまだまだ圧倒的に支持されており、次いでdate-fnsが徐々にシェアを伸ばしている様子。dayjsとluxon頑張れ!というような状態です。
画像元はこちらです。
https://www.npmtrends.com/date-fns-vs-dayjs-vs-luxon-vs-moment
GitHubやDocumentから見る
上述のnpmのダウンロード数では、dayjsよりもdate-fnsが上回っていましたが、GitHub Starはdayjsの方が上回っています。dayjsは今年の4月に生まれたばかりなので、これからさらに伸びていくことに期待です。
Documentについては、どのライブラリもよくまとめられていました。
その中でも、date-fnsは、欲しい情報がすぐに見つけられて好感を持ちました。
例えば、日付を加算するメソッドを探そうと
add
と入力したら一発で欲しい情報に辿り着けたのには感謝感激。URL: https://date-fns.org/docs/Getting-Started
ライブラリごとの情報は以下の通りです。
(2018/12/10 00:03時点)
moment
GitHub: https://github.com/moment/moment
Document: https://momentjs.com
GitHub Star: 39,459 / Latest commit: Oct 31, 2018 / created: Mar 1, 2011
dayjs
GitHub: https://github.com/iamkun/dayjs
Document: https://github.com/iamkun/dayjs/blob/master/docs/ja/README-ja.md
GitHub Star: 16,821 / Latest commit: Nov 20, 2018 / created: Apr 10, 2018
date-fns
GitHub: https://github.com/date-fns/date-fns
Document: https://date-fns.org
GitHub Star: 15,312 / Latest commit: Nov 14, 2018 / created: Oct 6, 2014
luxon
GitHub: https://github.com/moment/luxon
Document: https://moment.github.io/luxon
GitHub Star: 7290 / Latest commit: Nov 30, 2018 / created: Nov 30, 2015
サンプルコード
各ライブラリのサンプルコードを記載していきます。処理は前提で記載した以下3つの処理を各ライブラリごとに記載しています。
- 日付時刻をフォーマットする
- 日付の加算と減算を計算する
- 2つの日付の日数を計算する
momentのサンプル
momentは、前提に記載しているので省略します。
dayjsのサンプル
Moment.js の API との広い互換性を持ちます。上記の通り、dayjsはmomentと互換性があり、前提に記載したサンプルコードの
参照: https://github.com/iamkun/dayjs/blob/master/docs/ja/README-ja.md
moment
をdayjs
に置換しただけで作業は終了しました。moment経験者は学習要らずかもしれません。
❶. 日付時刻をフォーマットする
import dayjs from 'dayjs' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 dayjs(timestamp).format('YYYY/MM/DD HH:mm:ss') > 2018/12/16 07:00:00
import dayjs from 'dayjs' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 dayjs(timestamp).add(3, 'days').format('YYYY/MM/DD') > 2018/12/19 dayjs(timestamp).add(-3, 'days').format('YYYY/MM/DD') > 2018/12/13
import dayjs from 'dayjs' const timestamp1 = 1544911200 * 1000 // 2018/12/16 07:00:00 const timestamp2 = 1549663200 * 1000 // 2019/02/09 07:00:00 dayjs(timestamp1).diff(timestamp2, 'days') > -55 dayjs(timestamp2).diff(timestamp1, 'days') > 55
date-fnsのサンプル
他のライブラリは、メソッドチェーンで頑張っていくのに対して、date-fnsはコードがシンプルに書けて使いやすかったです。❶. 日付時刻をフォーマットする
import format from 'date-fns/format' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 format(timestamp, 'YYYY/MM/DD HH:mm:ss') > 2018/12/16 07:00:00
import format from 'date-fns/format' import addDays from 'date-fns/add_days' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 format(addDays(timestamp, 3), 'YYYY/MM/DD') > 2018/12/19 format(addDays(timestamp, -3), 'YYYY/MM/DD') > 2018/12/13
import differenceInDays from 'date-fns/difference_in_days' const timestamp1 = 1544911200 * 1000 // 2018/12/16 07:00:00 const timestamp2 = 1549663200 * 1000 // 2019/02/09 07:00:00 differenceInDays(timestamp1, timestamp2) > -55 differenceInDays(timestamp2, timestamp1) > 55
luxonのサンプル
明示的なAPIがluxonの1つの特徴です。moment, dayjs, date-fnsは、「timestamp」「ISO8601フォーマットの文字列」「Dateオブジェクト」等をAPIに渡せば日付時刻操作を行うことができます。// momentの場合 moment(1544911200 * 1000).format('YYYY/MM/DD HH:mm:ss') moment('2018-12-16T07:00:00+09:00').format('YYYY/MM/DD HH:mm:ss') moment(new Date('2018-12-16 07:00:00')).format('YYYY/MM/DD HH:mm:ss')
// luxonの場合 DateTime.fromMillis(1544911200 * 1000).toFormat('yyyy/MM/dd HH:mm:ss') DateTime.fromISO('2018-12-16T07:00:00+09:00').toFormat('yyyy/MM/dd HH:mm:ss') DateTime.fromJSDate(new Date('2018-12-16 07:00')).toFormat('yyyy/MM/dd HH:mm:ss')
それでは、サンプルコードです。
❶. 日付時刻をフォーマットする
import { DateTime } from 'luxon' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 DateTime.fromMillis(timestamp).toFormat('yyyy/MM/dd HH:mm:ss') > 2018/12/16 07:00:00
import { DateTime } from 'luxon' const timestamp = 1544911200 * 1000 // 2018/12/16 07:00:00 DateTime.fromMillis(timestamp).plus({ days: 3 }).toFormat('yyyy/MM/dd') > 2018/12/19 DateTime.fromMillis(timestamp).plus({ days: -3 }).toFormat('yyyy/MM/dd') > 2018/12/13
import { DateTime } from 'luxon' const timestamp1 = 1544911200 * 1000 // 2018/12/16 07:00:00 const timestamp2 = 1549663200 * 1000 // 2019/02/09 07:00:00 const dt1 = DateTime.fromMillis(timestamp1) const dt2 = DateTime.fromMillis(timestamp2) Math.floor(dt1.diff(dt2, 'days').days) > -55 Math.floor(dt2.diff(dt1, 'days').days) > 55
ファイルサイズ
上記サンプルコードをNuxt.js上に書き、それをanalyzeしてファイルサイズを確認しました。以下にリポジトリを公開しています。
GitHub: https://github.com/yagisuke/jikan-libraries
プロジェクト全体
ライブラリごと
ファイルサイズが軽量なものから並べています。dayjsとdate-fnsはmomentよりもだいぶ軽量だったので好印象でした。
luxonはmomentよりも重いようです。
ライブラリ名 | バンドルサイズ | 補足 |
---|---|---|
dayjs | ||
date-fns | サンプルコードで必要な format, addDays, differenceInDays のみに絞りました | |
moment | localeファイルはjaに絞りました | |
luxon |
まとめ
「moment」「dayjs」「date-fns」「luxon」をそれぞれみてきました。比較するのって楽しいですね
そして、比較した結果、今回は
dayjs
を採用することにしました採用した理由としては、以下の通りです。
- GitHub Starやメンテナンス頻度を確認して安心感があったこと
- momentで行なっていた処理を代替できること
- momentに比べて大幅にファイルサイズを削減できること
- momentの利用経験者は学習コストがかからないこと
- momentと互換性があり、乗り換えまでに時間がかからないこと
date-fns
と悩みましたが、決め手になったのは momentと互換性があり、乗り換えまでに時間がかからないこと
でした。momentユーザーの方は、この機会にぜひ
dayjs
を使ってみてはいかがでしょうか。以上、お付き合いいただきありがとうございました。
コメント
コメントを投稿