SQLiteでは、タイムゾーンは考慮されてないっぽい(2013-06-01調べ)
全ては文字列だと考えるといいかも。
保存した時の表記そのままで時間が返ってくる。
ただしCURRENT_TIMESTAMPはUTC
CURRENT_TIMESTAMP は 保存時にUTCで保存される
だから、取り出すときもUTCで出てくるので、表示スルときに、ローカル時刻として表示する必要がある。
取り出すときはlocaltime を使う。
sqlite> select datetime(datetime(),"localtime"); 2013-09-12 03:28:23 sqlite> select datetime(); 2013-09-11 18:28:31
確認してみた
SQLiteでテーブル作ったときに、よく注意する。
sqlite> .schema CREATE TABLE price_log ( price int, date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, data text );
SQLiteのテーブルに入った、時刻はINT秒かTEXTで入っていて、UTC時刻で入ってる。
取り出すときにlocalize されてタイムゾーンが考慮されて出てくる・・ってことはあり得ないので
UTC時刻で出てきます
特に current_timestamp の時に注意する。
sqlite> select datetime(date) from stock_price_log limit 2; 2013-05-18 23:59:41 2013-08-19 00:23:10 sqlite> select datetime(date, "localtime") from stock_price_log limit 2; 2013-05-19 08:59:41 2013-05-19 09:23:10 sqlite>
このように、localtime で変換して表示する必要がある。でないと時間ずれる
current _timestampを使わない場合
タダの文字列なら
CREATE TABLE price_log ( price int not null , date int not null, data text );
データべースには、UTCでデータを放り込んで、取り出すときに、タイムゾーンに併せた表示に取り出すのが無難なので。
UTCで保存して 取り出すときに datetime関数でローカル時刻にすると良いと思います。
追記
タイムスタンプ(ユニックス・エポック)の経過時間(秒数)は扱うときに次のようにして扱う。
SELECT datetime(mtime,'unixepoch') FROM locates; ## => UTC 日付になる
冒頭にも述べたが、SQLiteは「基本的に文字列」*1なので、完全な数字で入れてたときはかえって不便です。
UTCのタイムスタンプをローカルの時間として直して(変換して)表示する
SELECT datetime(datetime(mtime,'unixepoch'),'localtime') FROM locates;
このように、unixepoch と localtime の2回の変換を挟みます。
繰り返しになりますが、ぶっちゃけめんどくさいのでJST(TZ=Asia/Tokyo)を前提とした「文字列」で突っ込んでおくのが無難です。
なので、何が入ってるは(タイムスタンプはJSTかどうか、日付文字列はUTCなのか)をキチンとメモを残しておくと良いのです。
もう一つ無難な回答で言えば、ISO8601形式で「文字列」として突っ込むことなんだが、
## Z をつけてUTCを明示 2013-05-19T00:23:10Z ## ±をつけて TZを明示 2013-05-19T09:23:10+9:00
一見すると良さそうにも見えるけど、date関数群がうまく解釈してくれないことがあり、プログラミング言語側で苦労を強いられることになったりする。
ISO8601 形式で保存したとしても strftime のフォーマットをcreate table など何処かにメモしておかなくていけない。だったらもう「JSTだよ」って書いたほうが楽だよね。って話な?
更に追記
SQLiteが進化してて `2013-05-19T09:23:10+9:00` のような文字列をちゃんとUNIX Epochに変換できるようになってた。だから ±をつけて保存したヤツが無難だ。
他の人に以下に伝えて残すか。
ミスの防止のために、UTC時刻だよ!って教えてあげないといけません。
コメントを使います。
SQLlite3のcreate table文はそのままコメントが残るので、UTC時刻のときはUTCと書くべき
CREATE TABLE stock_price_log ( price int not null , -- 価格 date int not null, -- UTC のタイムスタンプ。取り出すときにdatetime(date,"localtime") で。 data text ); CREATE TABLE price_log ( price int not null , -- 価格 date int not null, -- JST時刻 data text );
などと、明示的に書いたほうがいいですね。
ときどきUTC時刻に、JST時刻を入れて9時間早くなってて、タイムゾーンをオフにしないと動かないテーブルを見かけますが、ああいうの何考えてるんだろうな。