俺の開発大作戦

Linux, Mac, Windows10 で 迷走する1開発を進めていく備忘録5

【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オブジェクトには無い機能が沢山備わっているので、是非利用をお勧めしたい。(詳しくは、こちらサイボウズ社のデペロッパー向けサイト)から!)

moment.js ライブラリーの読み込み

俺: 小林康典(KOBACHAN)

▼プロフィール畳む

▶プロフィール見る

時はネットが産声をあげた前世紀末、東京大手町に本社がある元国営の通信事業会社に新卒入社し、以降およそ10年間勤務して、インターネット系の新規事業立ち上げに複数携わる。

その後、退職して、ITベンチャーのスタートアップ参画を皮切りに、複数のIT/Web企業でプロダクトマネージャーを務めた後、縁あって現在の会員制ホテル&医療系事業会社へjoin。

元来、エンジニアばかりの環境で過ごしてきたが、ここは一般の非IT系事業会社でIT関連は全て外注。内製中心のアジャイル開発を企てるも、実際に技術がわかり手も動かせるIT担当者の存在はほぼ皆無で、参加直後から周囲の理解が得られず孤立無援の大ピンチ。

幾たびの紆余曲折を経て、技術やデザインに素養がある仲間を一人一人見つけアジャイル開発の世界に勧誘しては、知識・ノウハウを提供して地道に自律的な成長を促し、小規模ながらなんとか内製開発できるチームの形を整える。

現在、業務改善系ITプロダクトの企画およびシステム開発、ビッグデータ分析やAIビジネス転化への試行錯誤など、マルチに行い奮闘中。
(最近は、サイボウズ社のSaasサービス「キントーン」関連の開発多め。)

E-mail: contact@kobachan.biz

カテゴリー
月別アーカイブ
  • 2020 (1)
  • 2019 (2)
  • 2018 (5)
  • 2017 (6)