nodejsとpostgreSQLで文字列を日時に変換するときの注意
2015/04/05
Androidアプリでnew Date()を使って取得した日時を、nodejs使ってpostgreSQLに挿入するときにいろいろハマったのでメモ。
Androidの端末によって日時の文字列表現が微妙に違う
端末によって以下2種類を確認しています。GMT+09:00もJSTも同じ意味だから間違ってはないですが・・・
①Thu Mar 05 22:20:07 GMT+09:00 2015 ②Sun Mar 22 12:11:34 JST 2015
postgreSQLに①のようなGMT+09:00などの入った文字列を渡すとエラーとなる
nodejsからpostgreSQLに挿入するときに「Thu Mar 05 22:20:07 GMT+09:00 2015」を渡すと「型の入力構文が無効です」とエラーとなってしまいました。(エラーコード22007) ②のようなJSTの場合は特にエラーとなりませんが、この文字は無視されているようです。
postgreSQLのドキュメントを見ると、以下のようなことが書いてあります。また、Appendix A. 日付/時刻のサポートにもどう解析するか多少記述がありました。
- ISO 8601、SQL 互換、伝統的な PostgreSQL、その他を含むほとんどの適正と見なされるフォーマットを受け付けます。
というわけで、①をpostgreSQLに入れる場合、nodejsでnew Date()などして一度解析して別の文字列にする必要がありそうです。
nodejsのnew Date()に②のようなJSTなどが入った文字列を渡すとエラーとなる
postgreSQLに単純に文字列渡すのではなく、一度Date型にしたものを渡すようにしたのですが、今度はnew Date(“Sun Mar 22 12:11:34 JST 2015”)とすると「Invalid Date」となってしまいました。①だと正常に解析できます。
MDNのDateの説明見てみると以下のようなことが書いてあります。
- IETF 標準日付構文を受け付ける
- IETF-compliant RFC 2822 timestamps
nodejsとMDNの仕様が同じかはわからないですが・・・postgreSQLとnodejsの日時の解析方法は少し違うようです。
対処
とりあえず対策としてnodejsで受信した文字列にreplace(“JST”,”GMT+09:00″)をかけてdate型に変換してpostgreSQLに渡すことで対処できました。日本以外のゾーンに対応させようと思うと大変なのでよい方法ではない気もしますが・・・
var query = client.query({
text: "INSERT INTO xxx VALUES($1)",
values: [new Date(dateStr.replace("JST","GMT+09:00"))]
});