九保すこひ@フリーランスエンジニア|累計300万PVのブログ運営中
さてさて、この間Twitter
をぼんやり眺めていると、どんぶラッコさんのツイートが目に入り、衝撃を受けることになりました。
それは・・・・・・
Moment.js はすでに非推奨です😭
という事実です。
実際 Moment.js 公式のアナウンス でもこのことが言及されていて、以下のように言っています。
(超要約)
Moment.js は古い時代の JavaScript だから、新プロジェクトからは代替パッケージを使ったほうがいいかもね。
そして、その「代替パッケージ」として一番最初に登場するのが正式な後継パッケージ Luxon(「らくそん」と読むようです) でした。(2021.04.29 現在)
そこで❗
今回はこのLuxon
で日時を操作するため「実例記事」を書いてみることにします。
ぜひ皆さんのお役に立てましたら嬉しいです😊✨
「読み方が分からないパッケージは、
YouTube
でチェックしてます」
開発環境: Luxon 1.26.0
目次
- 1 日付オブジェクトを取得する
- 2 言語設定をする
- 3 日付データを取得する
- 3.1 年を4桁で取得する(例: 2021)
- 3.2 月を取得する(例: 4)
- 3.3 日を取得する(例: 30)
- 3.4 時間を取得する(例:15)
- 3.5 分を取得する(例: 51)
- 3.6 秒を取得する(例: 38)
- 3.7 ミリ秒を取得する(例: 345)
- 3.8 曜日を取得する(例: 水 or 水曜日)
- 3.9 Unixタイムスタンプを取得する(例: 946749845)
- 3.10 日本向けの日付を取得する(例: 2021/1/2)
- 3.11 日本語表記の日付を取得する(例: 2021年1月2日)
- 3.12 曜日つきの日付を取得する(例: 2000年1月2日(日))
- 3.13 曜日つきの日付を取得する(例: 2000年1月2日日曜日)
- 3.14 日本向けの時刻を取得する(例: 3:04)
- 3.15 日本向けの日時を取得する(例: 2000/1/2 3:04)
- 3.16 タイムゾーンを取得する(例: Asia/Tokyo)
- 3.17 指定したフォーマットで日時を取得(例: 2000.01.02)
- 3.18 日数を取得する
- 3.19 曜日を全て取得する
- 4 日付を操作する
- 5 日付をチェックする
- 6 日付を比較する
- 7 開発者向け
- 8 おまけ: Laravel(Webpack)で Luxon をインストール
- 9 ちなみに:なぜ Day.js を選ばなかったか
- 10 おわりに
日付オブジェクトを取得する
Luxon
からオブジェクトを取得するにはいくつかの方法がありますが、使い勝手がよさそうな順でご紹介します。
現在の日付・時間で取得
一番シンプルな取得方法で、「たった今」の時刻を取得します。
const dt = luxon.DateTime.now();
DB形式から取得(例: 2021-01-02 03:04:05)
MySQLなどデータベースから取得した日付データを元にする場合です。
const dt = luxon.DateTime.fromSQL('2000-01-02 03:04:05');
なお、日付のみでもOKです。
const dt = luxon.DateTime.fromSQL('2021-01-02');
ちなみにLaravel
との連携は以下のようにするといいでしょう。
const dt = luxon.DateTime.fromSQL('{{ $item->created_at }}'); // もしくはヘルパー関数の場合 const dt = luxon.DateTime.fromSQL('{{ now() }}');
※ その他、ミリ秒付きでもOKなどいろいろなパターンがありますが、一番馴染みのあるフォーマットになっていますので、「迷ったら fromSQL() を使ってみる」という流れでもいいかもしれません。
オブジェクトから取得(例: { year: 2000 … })
年・月・日 などのデータをセットする方法です。
const dt = luxon.DateTime.fromObject({ year: 2000, month: 1, day: 2 });
なお、年・月・日 が全て揃っている必要はなく、以下の場合は「2000/1/1 00:00:00」として取得できます。
const dt = luxon.DateTime.fromObject({ year: 2000 });
また、以下は「今日の1時2分3秒」になります。
const dt = luxon.DateTime.fromObject({ hour: 1, minute: 2, second: 3 });
指定フォーマットから取得
日付形式を指定する方法です。
例えば、「2000年、1月。日付は2日」という文字列からフォーマットを使って日付オブジェクトを取得してみましょう。
const text = '2000年、1月。日付は2日'; const dt = luxon.DateTime.fromFormat(text, 'yyyy年、M月。日付はd日');
JavaScript の日付オブジェクトから取得
JavaScript
で使えるノーマルな日付オブジェクトを使う方法です。
const dt = luxon.DateTime.fromJSDate(new Date());
なお、これは以下と同じになります。
const dt = luxon.DateTime.now();
言語設定をする
全体的に言語設定をする場合は、luxon
を利用する前に以下のコードをセットしておく必要があります。
luxon.Settings.defaultLocale = 'ja';
また、個別にロケールを変更したい場合は以下のようにsetLocale()
を使ってください。
dt.setLocale('ja').toFormat('EEE');
日付データを取得する
年を4桁で取得する(例: 2021)
const year = dt.year;
月を取得する(例: 4)
const month = dt.month;
日を取得する(例: 30)
const day = dt.day;
時間を取得する(例:15)
const hour = dt.hour;
もし、12時間単位で取得する場合はtoFormat()
を使ってください。
const hour = dt.toFormat('h');
分を取得する(例: 51)
const minute = dt.minute;
秒を取得する(例: 38)
const second = dt.second;
ミリ秒を取得する(例: 345)
const millisecond = dt.millisecond
曜日を取得する(例: 水 or 水曜日)
luxon.Settings.defaultLocale = 'ja'; // 言語設定が必要です。 const dayOfWeek = dt.weekdayShort; // 水
もしくは曜日を省略しない場合です。
luxon.Settings.defaultLocale = 'ja'; // 言語設定が必要です。 const dayOfWeek = dt.weekdayLong; // 水曜日
Unixタイムスタンプを取得する(例: 946749845)
const timestamp = dt.toSeconds();
なお、ミリ秒の場合はこちら。
const timestamp = dt.toMillis();
日本向けの日付を取得する(例: 2021/1/2)
const date = dt.toLocaleString();
日本語表記の日付を取得する(例: 2021年1月2日)
const date = dt.toLocaleString(luxon.DateTime.DATE_FULL);
曜日つきの日付を取得する(例: 2000年1月2日(日))
const date = dt.toLocaleString(luxon.DateTime.DATE_MED_WITH_WEEKDAY);
曜日つきの日付を取得する(例: 2000年1月2日日曜日)
const date = dt.toLocaleString(luxon.DateTime.DATE_HUGE);
日本向けの時刻を取得する(例: 3:04)
const time = dt.toLocaleString(luxon.DateTime.TIME_SIMPLE);
日本向けの日時を取得する(例: 2000/1/2 3:04)
const time = dt.toLocaleString(luxon.DateTime.DATETIME_SHORT);
タイムゾーンを取得する(例: Asia/Tokyo)
const timezone = dt.zoneName;
指定したフォーマットで日時を取得(例: 2000.01.02)
const date = dt.toFormat('yyyy.MM.dd');
なお、フォーマットに使われるキーワードは以下を参考にしてください。
📝 参考URL: https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens
日数を取得する
例えば、「今月は何日あるの?」が知りたい場合です。
const days = dt.daysInMonth;
また、年間の場合はこちら。
const days = dt.daysInYear;
※うるう年の場合は366日になります。
曜日を全て取得する
月〜日までのデータを全て取得する方法です。
const weekdays = luxon.Info.weekdays(); // 👉これは ["月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日", "日曜日"]
もし省略バージョンの曜日を取得する場合はshort
をつけます。
const weekdays = luxon.Info.weekdays('short'); // 👉 これは、["月", "火", "水", "木", "金", "土", "日"]
日付を操作する
日時を進める(例: 2000/1/2 → 2000/1/5)
const newDt = dt.plus({ days: 3 }); // 3日進める
もちろん、days
だけでなくその他のパラメータも使えます。
const newDt = dt.plus({ hours: 3, // 3時間進める minutes: 4 // 4分進める });
日時を戻す
こちらも「日時を進める」と同じくminus()
を使うことで実装できます。
const newDt = dt.minus({ days: 2, hours: 3, // 3時間進める minutes: 4 // 4分進める });
指定した日時へ移動する
例えば、「2000/1/2 03:04:05」から「2001/2/3 04:05:06」に移動する場合です。
const dt = luxon.DateTime.fromSQL('2000-01-02 03:04:05'); const newDt = dt.set({ year: 2001, month: 2, day: 3, hour: 4, minute: 5, second: 6 });
もちろん、全ての項目をセットする必要はなく、「年だけ」とか「月と日だけ」を指定することもできます。
年・月・日などの開始位置へ移動
ある開始地点へ移動するにはstartOf()
を使います。
例えば、現在が「2000/5/3 03:04:05」として、月の始めに移動してみましょう。
const newDt = dt.startOf('month'); // 2000-05-01 00:00:00
もちろん、month
だけでなくyear
やday
、hour
などでもつかえます。
年・月・日などの終了位置へ移動
ある終了地点へ移動するにはendOf()
を使います。
例えば、現在が「2000/5/3 03:04:05」として、月の終わりに移動してみましょう。
const newDt = dt.endOf('month'); // 2000-05-31 23:59:59
もちろん、month
だけでなくyear
やday
、hour
などもつかえます。
日付をチェックする
日付として正しいかチェックする
例えば、「2000-02-31」はありえない日付ですが、こういったものをチェックする方法です。
const dt = luxon.DateTime.fromSQL('2000-02-31'); // 👈 ありえない日付 if(!dt.isValid) { console.log('日付が正しくありません!'); }
うるう年かどうかチェックする
例えば、2000年はうるう年のため366日ありますが、こういったものをチェックする方法です。
const dt = luxon.DateTime.fromSQL('2000-01-01'); // 👈 2000年は、うるう年です if(dt.isInLeapYear) { console.log('うるう年です!'); }
同じ「年」や「月」かをチェックする
例えば、2つの日時が同じ年&月のものかどうかをチェックする方法です。
const dt1 = luxon.DateTime.fromSQL('2000-01-02'); const dt2 = luxon.DateTime.fromSQL('2000-01-03'); if(dt1.hasSame(dt2, 'month')) { console.log('同じ年・月です!'); }
ここで重要なのはmonth
とした場合でも、単純に月だけを比較していないという部分です。つまり、上の例で言うとdt2
が2001-01-03
の場合、hasSame()
はfalse
となります。
日付を比較する
2つの日付の差を取得する
例えば、以下2つの日付を比較して「どれだけ日数が違うか」を取得する場合です。
- 2000-01-02
- 2001-02-03
const dt1 = luxon.DateTime.fromSQL('2000-01-02'); const dt2 = luxon.DateTime.fromSQL('2001-02-03'); const diff = dt1.diff(dt2, 'days'); // 👈 months などもでもOKです const diffDays = diff.days; // -398
現在時間との差を取得する
const dt1 = luxon.DateTime.fromSQL('2000-01-02'); const dt2 = luxon.DateTime.fromSQL('2001-02-03'); const diff = dt1.diffNow('days'); const diffDays = diff.days; console.log(diffDays)
どちらが「先 or 後」の日時かを判別する
>
や>=
などの比較演算子が使えます。
const dt1 = luxon.DateTime.fromSQL('2000-01-02'); const dt2 = luxon.DateTime.fromSQL('2001-02-03'); if(dt1 < dt2) { console.log('dt1 の方が古い日時です。'); }
開発者向け
中身を確認したい場合
開発者としてシンプルに日時の中身を取得したい場合はtoString()
を使うといいでしょう。
console.log(dt.toString());
あたかも指定した日時を現在時刻とする
luxon.Settings.now = () => { return new Date('2000-01-01'); }; const currentDateTime = luxon.DateTime.now().toString(); // 👈 2000-01-01 になる
おまけ: Laravel(Webpack)で Luxon をインストール
このブログではLaravel
の記事をよく公開していますので、おまけとしてLaravel
にLuxon
をインストールする方法をご紹介します。
まず以下のコマンドでパッケージをインストールしてください。
npm install --save luxon
インストールが完了したら、ビルド用のコードを追加します。
resources/js/app.js
// 省略 window.luxon = require('luxon'); // 👈 ここを追加しました
これでビルドされたjs
ファイルを読み込めばCDN
と同じように使うことができます。
<html> <body> <script src="/js/app.js"></script> <script> const dt = luxon.DateTime.now(); </script> </body> </html>
ちなみに:なぜ Day.js を選ばなかったか
完全に「これは個人の感想です」というやつなのですが、Day.js
があまり私には合わなかったので、その理由も備忘録として書いておくことにしました。
理由としてはシンプルに、
「うーん、JavaScript のそういうところが好きじゃないからパッケージを使いたいんだけど…」
というものです。
例えば、「年」「月」「日」を取得するコードを見てみましょう。
const dt = dayjs('2000-01-01'); console.log(dt.year()); console.log(dt.month()); // これは 0 になる(0〜11) console.log(dt.day()); // これは曜日になるので、date() が正解
このように、month()
は0〜11
で返ってきますし、day()
では「日」を取得することができません。
これって、以前公開した記事 JavaScriptのハマりどころ全11件! のように微妙にワナが用意されてるような状態で、あまり直感的ではないと感じました。(プログラム初学者にもやさしくないですよね…😫)
今回の記事を書き始めたときは、「軽量に動く」&「スターが一番多い」Day.js
を検討していましたが、こういう理由で結局Luxon
を選ぶことになりました。
おわりに
ということで、今回はJavaScript
の日付パッケージLuxon
の使い方をまとめてみました。
正直なところ、まだまだ他にも機能はたくさんあるのですが、さすがに多すぎるので、「開発するには最低限これだけあればいいだろう」と思うものをピックアップしてみました。
ちなみに、moment.js
と比べてみた感想ですが、moment.js
は以下のように短いコードでインスタンスを取得できるので、やはりこっちの方が好きかなというイメージでした。
const dt = moment('2000-01-01', 'YYYY-MM-DD');
これがLuxon
の場合は、DateTime
をつけないといけません。
const dt = luxon.DateTime.fromSQL('2000-05-02');
なので個人的には、シンプルに以下のようにaxios
っぽい感じでいいのにな、と感じました。(Settings
などと分けているので仕方ないといえば仕方ないですが・・・)
// ⚠これらは間違った書き方です! const dt = luxon.fromSQL('2000-01-02'); // もしくは moment.js のように const dt = luxon('2000-01-02');
・・・とは言え、この辺は実際の案件で使っていけばすぐ慣れる気もしています。ぜひ皆さんもチェックしてみてくださいね。
ではでは〜❗
「メガネの鼻の支えが
1本折れました・・・😫」