それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

SQLiteのタイムゾーン

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関数でローカル時刻にすると良いと思います。


他の人に以下に伝えて残すか。

ミスの防止のために、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時間早くなってて、タイムゾーンをオフにしないと動かないテーブルを見かけますが、ああいうの何考えてるんだろうな。