Node-REDで日付時刻文字列を作成する

先日のエントリでデータの画像のアーカイブを取るためにNode-REDfunctionノードを使用してファイル名をYYYYMMDDhhmm.jpgというような形式の文字列を作成していました。

参考

uepon.hatenadiary.com

f:id:ueponx:20220216013852p:plain

個人的には折角Node-REDを使用しているので極力functionノードは使用したくないものです。可読性などを高めるのであればfunctionノードを用いたほうがフロー自体はスッキリしますが、コードをあまり書かなくても良いという利点があまり活かせないので可能な限り使わないで表現したいと常々思っています。

今回はわりと使用する頻度が高そうな日付時刻文字列を作る方法をまとめておこうと思います。今回のエントリーではfunctionノードを使用しない方法も説明します。

  • functionノードを使用するパターン
  • momentノードを使用するパターン
  • JSONataを使用するパターン

functionノードを使用するパターン

functionノードのプロパティのコードにJavascriptのコードを記述していきますが、以下を参考にさせていただきました。

参考

qiita.com

基本的にはJavascriptDateオブジェクトの使用方法になるので、以下のようなコードを書いていくことになります。

f:id:ueponx:20220216022222p:plain

注意があるとすれば月の数値コードでいうdate.getMonth()は範囲が0から11になっているので数値化するときに1を加えている点でしょうか。

// ペイロードから日付オブジェクトを生成
let date = new Date();

//年・月・日を取得する
let year = date.getFullYear();
let month = date.getMonth()+1;
let day = date.getDate();
month = ("0" + month).slice(-2);
day = ("0" + day).slice(-2);
//時・分・秒を取得する
let hour = date.getHours();
let minute = date.getMinutes();
let second = date.getSeconds();
hour = ("0" + hour).slice(-2);
minute = ("0" + minute).slice(-2);
second = ("0" + second).slice(-2);

// 日付文字列に変換して再度ペイロードをセット
msg.payload = year+month+day+"_"+hour+minute+second;
// 次のノードへmsgオブジェクトを返す
return msg;

f:id:ueponx:20220216022228p:plain

f:id:ueponx:20220216022238p:plain

それほど難しいコードではありませんが、正直スペルミスなども考えられるので折角のNode-RED環境化ではあまり使いたくないです。

momentノードを使用する

次に紹介するのは処理にmoment.jsを使用する拡張ノードmomentノードを使用するパターンになります。

以下の拡張ノードを使用していきます。

flows.nodered.org

通常の拡張ノードと同様に【三】→【パレットの管理】から【ノード追加】タブを選択してインストールを行います。

f:id:ueponx:20220216232612p:plain

インストール後はパレットのformatsカテゴリに2つのノードが追加されます。

f:id:ueponx:20220216234229p:plain

今回は2つうちDate/Time formatterノードを使用します。

f:id:ueponx:20220216234255p:plain

使用する拡張ノードの準備ができたので、injectノードDate/Time formatterノードdebugノードを使用して以下のようなフローを作成します。

f:id:ueponx:20220216233627p:plain

Date/Time formatterノードのプロパティは以下の様に設定をします。このノードはフォーマット変換をするだけのものになるため変換対象の日付時刻の取得は別途行う必要がある点が注意です(今回はinjectノードで取得)。msg.payloadを入力として、日付時刻文字列の出力フォーマット、ロケールタイムゾーンの設定をすることで、日付時刻文字列を取得することができます。

f:id:ueponx:20220216234058p:plain

このフローを実行することで以下のような結果が得られます。

f:id:ueponx:20220216234102p:plain

functionノードよりも容易に結果を求めることができました。ロケールタイムゾーンも変換できるのが利点かもしれません。

JSONataを使用するパターン

次のやり方はJSONataを使用しての日付時刻文字列の取得になります。先程は拡張ノードを別途インストールして行っていましたが、今回の方法はインストールするものは特にありません。

JSONata は、JSON データ構造を照会および変換するための式言語です。

ということなのですが、実はJSONataには取得したデータを編集する機能が豊富に容易されています。 今回はその機能を使用するというものになります。

injectノードchangeノードdebugノードを使用して以下のようなフローを作成します。

f:id:ueponx:20220216234734p:plain

changeノードのプロパティの設定で、ルールの設定で以下のように設定をします。

  • 機能 … 【値の代入】
  • 代入する変数 … msg.payload
  • 代入する値のフォーマット … JSONata
  • 代入する値 … $fromMillis(payload,'[Y0001][M01][D01]_[H01][m01][s01]','+0900')

フォーマットの変更はプルダウンメニューから選択を行います。

f:id:ueponx:20220216235409p:plain

代入する値で使用しているのは$fromMillis()はミリ秒の値から日付時刻文字列を引数で指定した形式取得するものになります。

f:id:ueponx:20220216234908p:plain

このフローをデプロイして実行すれば以下のように出力が行われます。

f:id:ueponx:20220216235547p:plain

こちらも比較的簡単にかつデフォルトの機能だけで取得することができました。JSONataは非常にたくさんの機能を持っているので使いこなせればfunctionノードとほぼ同様のことができるようになるのではないかと感じます。

今回使用したフローGitHubにおいてありますので、テストなど使用してみてください。

github.com

おわりに

Node-REDをつかって日付時刻文字列を取得するといった簡単な処理を調べてみました。functionノードに逃げがちなところを拡張ノードに変える、JSONataの利用に変えるなどいろいろやり方がありました。特に今回はJSONataの使用方法がこんな方法もあるのかと驚きました。これまでJSONataJSONから値を取得するクエリ的な位置づけでしか使ったことはなかったのですが、色々な用途がこれから見つけられそうです。

JSONataについては以下のものが参考になるかなと思います。

参考

jsonata.org

qiita.com

qiita.com

/* -----codeの行番号----- */