JavaScriptのDateオブジェクトをJSON.stringify()したときの時間のずれについて

こんにちは!ぐちです。

最近はCakePHPを使って業務改善のシステムを作っていたのですが、そこで出くわした問題についてご紹介します。

タイムゾーン

日付や時間を扱う際に、いつも問題になるのがタイムゾーンです。世界中の標準時間が決められているのはご存知の通りですが、基準時間から何時間のプラスやマイナスがあるかという、あれです。

日本は世界標準時間から9時間進んだJSTというタイムゾーンに分類されます。プログラミング中にだいたいのケースでこのタイムゾーンにハマることがあるんです。笑

今回もJavascriptの標準APIを使った際にハマっちゃいました。。。

JSON.stringify

このJSON.stringify()ですが、オブジェクトをJSONフォーマットの文字列に変換してくれる便利な関数なんですが、JavascriptのDate型を含めた際にイレギュラーな動きをしました。

JSTの日付時間を持ったオブジェクトをJSON文字列にすると、UTC(世界標準時間)に変換されてしまうんです。変換というか、タイムゾーンを考慮せずに問答無用でUTCにしてしまうんです。今回は画面上で保持しているオブジェクトをWebAPIにPOSTするときに勝手にUTCになってしまっていて、苦労しました。笑

で、どうしたかというと

Dateオブジェクトはstringify()で文字列に変換される際にtoJSON()という関数を使っており、これをオーバーライド(呼び方あってるかな。。)する形で対応することにしました。

こちらの記事でまんまやりたいことを記事にされていたので、有難く丸コピさせて頂きました。笑

prototype

Javascriptにはprototypeという親の属性を引き継がせるためのオブジェクトが用意されています。※このあたりの説明はググって頂くとして。。。。

で、そのオブジェクト経由で対象の関数をオーバーライド(呼び方・・・)するという対処をされていました。今回僕がハマった問題はこれで解決するので、根本的な解決ではないにしろ、まぁとりあえずこれで・・・といった感じです。

コードを載せておきます。詳細は前述の記事をご参考ください。

Date.prototype.toJSON = function() {
    return this.getFullYear() + '-' + ('0'+(this.getMonth()+1)).slice(-2) + '-' + ('0'+this.getDate()).slice(-2) + 'T' +
     ('0'+this.getHours()).slice(-2) + ':' + ('0'+this.getMinutes()).slice(-2) + ':' + ('0'+this.getSeconds()).slice(-2) + '.000Z';
}

このコードを共通部分に定義しておけば、まぁなんとかなります。笑

では今回はこの辺で。