web-dev-qa-db-ja.com

現在のタイムスタンプをティックとしてSQLiteに保存するにはどうすればよいですか?

日付をティックとして保存するSQLiteデータベースがあります。デフォルトのISO8601形式を使用していません。次のように定義されたテーブルがあるとしましょう。

CREATE TABLE TestDate (LastModifiedTime DATETIME)

SQLを使用して、現在の日付と時刻を挿入したいと思います。以下のステートメントのいずれかを実行すると、日付と時刻がティックではなく文字列として格納されることになります。

INSERT INTO TestDate (LastModifiedTime) VALUES(CURRENT_TIMESTAMP)
INSERT INTO TestDate (LastModifiedTime) VALUES(DateTime('now'))

SQLite documenation を見てきましたが、現在のタイムスタンプをティックで取得するオプションが見つからないようです。

もちろん、C#でパラメーターを定義し、その値をSystem.DateTimeとして格納することもできます。これにより、日時がティック単位でデータベースに保存されます。

私がやりたいのは、SQLステートメント内から直接現在のタイムスタンプを挿入および更新できるようにすることです。どうすればよいですか?

編集:

データをティックとしてデータベースに格納する理由は、日付がADO.Netデータプロバイダーによって格納されているのと同じ形式で格納されているため、データがADO.Netプロバイダーを使用してクエリされた場合も同様です。 System.DataTime.Netタイプとして正しく取得されます。

11
Elan

SQLiteのドキュメント および日付番号の変換に関するその他の情報をさらに調査した結果、次の式が見つかりました。これにより、正しい結果が得られるようです。

INSERT INTO TestDate(LastModifiedTime)
    VALUES(CAST((((JulianDay('now', 'localtime') - 2440587.5)*86400.0) + 62135596800) * 10000000 AS BIGINT))

組み込みの日時形式として利用できると期待するものを作成するのは面倒な方法のようです。特に、データベースが日時値のティック単位の格納をサポートしている場合はそうです。うまくいけば、これは他の人にも役立つようになります。

更新:

上記の式は、夏時間に関しては完全ではありません。現地時間の計算については、SQLiteドキュメントのセクション 警告とバグ を参照してください。

2
Elan

SQLiteのこの特定の奇妙さは、私に多くの苦痛を引き起こしました。

簡単な方法-通常のタイムスタンプとして保存および取得

create table TestDate (
        LastModifiedTime datetime
);
insert into TestDate (LastModifiedTime) values (datetime('now'));
select datetime(LastModifiedTime), strftime('%s.%f', LastModifiedTime)  from TestDate;

出力:2011-05-10 21:34:46 | 1305063286.46.000

面倒な方法-UNIXタイムスタンプとして保存および取得

Strftimeを使用して、ティック単位の値を取得できます。さらに、UNIXタイムスタンプ(ティックとほぼ同等)を格納するために、秒数を一重引用符で囲むことができます。

 insert into TestDate (LastModifiedTime) values ('1305061354');

SQLiteは、これをUNIXタイムスタンプではない他の値として内部的に保存します。取得時に、UNIXタイムスタンプとして取得するようにSQLiteに明示的に指示する必要があります。

 select datetime(LastModifiedTime, 'unixepoch') FROM TestDate;

現在の日付と時刻を保存するには、strftime( '%s'、 'now')を使用します。

 insert into TestDate (LastModifiedTime) VALUES (strftime('%s', 'now'));

完全な例:

create table TestDate (
        LastModifiedTime datetime
);      
insert into TestDate (LastModifiedTime) values (strftime('%s', 'now'));
select datetime(LastModifiedTime, 'unixepoch') from TestDate;

Sqlite3で実行すると、次のスクリプトが出力されます。

2011-05-10 21:02:34 (or your current time)
20
MrAnonymous

以下は、UNIXエポックからのミリ秒数を返します。

SELECT (strftime('%s', 'now') - strftime('%S', 'now') + strftime('%f', 'now')) * 1000 AS ticks

これは、Unixエポックからの秒数(%s)を取得し、現在の時刻の秒数(%S)、秒数を加算小数点以下%f)、結果に1000を掛けて、秒からミリ秒に変換します。

減算と加算は、結果を歪めることなく値に精度を追加することです。 SQLiteのドキュメントに記載されているように、同じステップ内で 'now'を使用すると、すべて同じ値が返されます。

1
Rob