Node.js date-fns ライブラリを使って February 28, 2022 at 08:45AM な表記をパースするメモ

Node.js date-fns ライブラリを使って February 28, 2022 at 08:45AM な表記をパースするメモです。

date-fns 便利

Moment.js を便利に使ってたんですが、メンテナンスモードになってしまってしまって、新しいライブラリを探していました。

時期的に絶妙で日付を精密に加工する開発を最近していたときに、開発が終わっている Moment.js のナレッジ詰むより、新しいナレッジ追いたいなと言うのもありました。

JSの日付ライブラリは、どれを使えばいいのかまとめ

このあたりも参考にしつつ、date-fns を使っていくことにしました。

こんなあたりが好みでした。

February 28, 2022 at 08:45AM な表記をどうにかしたい

さて、この date-fns で感動した話なわけです。

Node.js date-fns ライブラリを使って February 28, 2022 at 08:45AM な表記をパースしまて、めっちゃ便利だなと思いまして。

IFTTT で使われるアメリカ式の月を名前で書く日時表記を JavaScript で ISO 8601 的な日付に変換するメモ – 1ft-seabass.jp.MEMO

以前、ゴリ押しの JavaScript コードでなんとかしてたんですが、ようやく date-fns でのパースでもできるじゃんという境地に至ったのでメモしておきます。使いこなせるようになってきた。

date-fns parse の使い方はこちら。さまざまなパースのパターンがあって、自分でいちいちコード書くよりもスマートに変換できます。

parse('23 AM', 'HH a', new Date())

サンプルにあるように、この場合 HH というパターンで24時間扱いの時間部分、a というパターンでAM・PM が取得できます。

使ってみる

早速やってみましょう。

npm i date-fns

date-fns をインストールしている状態で、以下のコードでうまくいきました。

const parse = require('date-fns/parse');

const stringDatetimeSample = 'February 28, 2022 at 08:45AM';

// 変換成功後 Date 型で返す
const dateParsedDatetimeSample = parse(stringDatetimeSample,"MMMM dd, yyyy 'at' hh:mma",new Date());

// UTC ISOフォーマットで返答
// UTC 2022-02-27T23:45:00.000Z = JST 2022-02-28T08:45:00.000+0900
console.log(dateParsedDatetimeSample.toISOString());

hh:mmaa の部分でAM/PM、 MMMM で January, February, …, December の表記をすんなり変換できて素晴らしいですね。

また、'at' にすることで、ここは、パースに関係するパターンと関係ない at という文字ですよとエスケープしてます。 a も t もパターンで扱われる可能性があるからエスケープする必要がありました。

余談 HH:mma だと納得のエラーが起きる

ちなみに、”MMMM dd, yyyy ‘at’ HH:mma” だとエラーがおきました。正解の hh:mmHH:mm にしてたときにエラーってことですね。

RangeError: The format string mustn’t contain HH and aa at the same time
RangeError:フォーマット文字列に HHaaを同時に含めることはできません

しかしながら納得。

これは、HH だと0-24時の時間をパースするんですが aaa を扱う場合は AM/PM が絡むわけで、自然と時間は 0-12 の扱いになるわけですね。21:00PM というのが無いわけで、同時に使わないでねと言うエラー。

hh:mmにしたら、すんなり変換できました。