【kintone カスタマイズ Tips】JavaScriptで日付を扱う場合の罠
JavaScriptのDateオブジェクトで日付を扱う際は実に落とし穴が多く、初心者は必ずといっていいほど躓いてしまう。JavaScriptによるkintoneカスタマイズを初めたビギナーが日付を扱った際に、どうも上手くできないと相談を受けることが多かったので、躓きかぎなポイントなどを記事でまとめておこうと思う。
1. 躓くポイント①〜「月」取り扱いの罠
まずは、百聞は一見に如かずで、実際に現在の日付を取得して、月の数字を抜いてみる。
const date = new Date(); //Mon Feb 18 2019 16:04:22 GMT+0900 (日本標準時) console.log(date.getMonth()); //1
あれ、2じゃないの?となる。笑 日付型の数値から値を取り出す方法としてDateオブジェクトではgetMonthメソッドが用意されているが、これを実行すると、1始まりではなく0~11を返すので、実際の月を得るには +1してあげなければならないのだ。こんなの事前に知っておかないと戸惑うよね。笑
2. 躓くポイント②〜「年」取り扱いの罠
まだまだあるJavaScriptによる日付の罠。年取得ではgetYearとgetFullYearの2つのメソッドがある。このうち、getYearは、殆どの人が下二桁の数値を返すと思いがちになるが、実際には1900を引いた数字が返る。笑
const date = new Date(); //Mon Feb 18 2019 16:04:22 GMT+0900 (日本標準時) console.log(date.getYear()); //119
JavaScript開発者は世紀末論者で2000年を迎えることを想定していなかったのか!?本当にあった「西暦2000年問題」を体現してるようで、なんだか胸熱だ。笑 まったく実用的ではないので、フル4桁の数値を得る getFullYearのみを使うのが吉。
3. 躓くポイント③〜タイムゾーン補完の罠
Javascript は、日付文字列を日付にパースする際に時刻情報を持たないとタイムゾーンを勝手に補完するが、それが一定しない。「/」区切りだとJST(日本標準時)と解釈され0時の扱いとなり特に問題ないが、「-」区切りだと元々UTC(世界標準時)として解釈されて+0900が補完され9時になる。
const date = new Date('2019/02/18'); //Mon Feb 18 2019 00:00:00 GMT+0900 (日本標準時) const date = new Date('2019-02-18'); //Mon Feb 18 2019 09:00:00 GMT+0900 (日本標準時)
タイムゾーン補完の解釈があいまいなのは、これだけではない。マシンが日本語環境の場合、大抵の場合は jst のままで扱われるが、例えばJSON化した場合や、kintone でも REST APIのGETメソッドで日時フィールドを取り出した際は、jstとして解釈された後にUTC日時に置き換えて出力されるなど、実際に日付が変わってしまうので実にやっかいだ。
・JSON化した場合の出力結果const date = new Date('2019/02/18'); //Mon Feb 18 2019 00:00:00 GMT+0900 (日本標準時) console.log(date.toJSON()); //2019-02-17T15:00:00.000Z console.log(JSON.stringify(date)); //2019-02-17T15:00:00.000Z
こうした罠を回避するために、出力データがどのタイムゾーンで扱われるか、不要なところで±9時間の処理が行われていないか気を配る必要があり、扱いが実に煩わしい。
4. moment.js を使ってみよう
dateオブジェクトの不足点を補う JavaScript のライブラリーとして、moment.js がある。業務アプリ内で日付を複雑に扱う場合には、最近はこのライブラリをできる限り使用している。このライブラリーを読み込んで momentオブジェクトが使えるようになれば、日付文字列を日付にパースする場合も文字列の型によってタイムゾーン解釈の揺れは発生せず、日本語環境であればJSTでの出力が標準になる。
console.log(moment('2019/02/18')._d); //Mon Feb 18 2019 00:00:00 GMT+0900 (日本標準時) console.log(moment('2019-02-18')._d); //Mon Feb 18 2019 00:00:00 GMT+0900 (日本標準時)
JSONデータやkintone のREST APIでの出力する日時データなど、UTCで出力される前提のものは、momentオブジェクトで再出力すればJSTに変換される。+9時間するよりは多少は楽か。
const date = JSON.stringify(moment()); //2019-02-17T15:00:00Z moment(date)._d; //Mon Feb 19 2019 00:00:00 GMT+0900 (日本標準時)
なお、月が0~11で出力されるのは、dateオブジェクトと変わらず・・・。
const date = moment(); //Mon Feb 18 2019 16:04:22 GMT+0900 (日本標準時) date.month(); //1
kintone での moment.js の使用方法は、[設定] - [JavaScript / CSS でカスタマイズ] にて、Cybozu CDNからライブラリを読み込むだけで良い。[何日後]のような計算を簡易に行えるメソッドなど、dateオブジェクトには無い機能が沢山備わっているので、是非利用をお勧めしたい。(詳しくは、こちらサイボウズ社のデペロッパー向けサイト)から!)