DATETIME値はSQLiteでどのように機能しますか?


110

Androidアプリを作成していますが、作成レコードの日時を保存する必要があります。ただし、SQLiteのドキュメントでは、「SQLiteには日付や時刻を格納するためのストレージクラスが用意されていない」とあり、「TEXT、REAL、またはINTEGER値として日付と時刻を格納できます」としています。

あるタイプを別のタイプで使用する技術的な理由はありますか?また、単一の列に日付を行から行への3つの形式のいずれかで格納できますか?

後で日付を比較する必要があります。たとえば、私のアプリでは、日付Aから日付Bまでの間に作成されたすべてのレコードを表示します。真のDATETIME列がないと比較が難しくなるのではないかと心配しています。


回答:


83

SQliteには特定の日時タイプはありません。あなたは使用することができTEXTREALあるいはINTEGER、あなたのニーズに合った方、種類。

ドキュメントから直接

SQLiteには、日付や時刻を保存するためのストレージクラスがありません。代わりに、SQLiteの組み込みの日付と時刻関数は、日付と時刻をTEXT、REAL、またはINTEGER値として保存できます。

  • ISO8601文字列としてのテキスト( "YYYY-MM-DD HH:MM:SS.SSS")。
  • ユリウス日としてのREAL。紀元前4714年11月24日のグリニッジでの正午からの、先天性グレゴリオ暦による日数。
  • INTEGER(Unix Time)、1970-01-01 00:00:00 UTCからの秒数。

アプリケーションは、日付と時刻をこれらの形式のいずれかで保存し、組み込みの日付と時刻の関数を使用して形式間を自由に変換することを選択できます。

SQLiteの組み込みの日付と時刻関数はここにあります


11
注意すべき重要な点-日付を保存するすべてのメソッドは、標準の=、<、>、およびBETWEEN演算子を使用して比較できる形式を使用します。
Larry Lustig、2015

2
「SQLiteには、日付や時刻を格納するために別に用意されたストレージクラスはありません」-ドキュメントに記載されていないDATEおよびDATETIMEタイプがあることを除いて
Slabko

12
@Slabkoありません。SQLiteでは、列の宣言された型として(DATETIMEを含む)何でも許可されます。これに基づいて、その列にストレージクラスとの類似性を与えます(ドキュメントのDATETIMEでこれがどのように機能するかの例も含まれています)。列の各エントリは実際には異なるストレージクラスを持つことができるため、その親和性はヒントに似ています。ストレージクラスは、まだタイプよりも弱いステップであり、複数のタイプによってサポートされます。つまり、DATETIMEを使用できます。いいえ、実際にはタイプまたはストレージクラスとしてサポートしていません。はい、ドキュメントには実際に「DATETIME」という単語が含まれています。
Jasper

20

SQLiteには、日付や時刻を保存するためのストレージクラスがありません。代わりに、SQLiteの組み込みの日付と時刻関数は、日付と時刻をTEXT、REAL、またはINTEGER値として保存できます。

ISO8601文字列としてのテキスト( "YYYY-MM-DD HH:MM:SS.SSS")。ユリウス日としてのREAL。紀元前4714年11月24日のグリニッジでの正午からの、先天性グレゴリオ暦による日数。INTEGER(Unix時間)、1970-01-01 00:00:00 UTCからの秒数。アプリケーションは、日付と時刻をこれらの形式のいずれかで保存し、組み込みの日付と時刻の関数を使用して形式間を自由に変換することを選択できます。

そうは言っても、私はINTEGERを使用して、Unixエポック(1970-01-01 00:00:00 UTC)以降の秒数を格納します。


1
私もこれが好きです。標準の日付/時刻関連クラスはとにかくlongsによって内部的にサポートされており、longを比較するのは非常に簡単です。
からくり2013年

1
@dtmilanoなぜここでは文字列ではなくINTEGERを使うのですか?
IgorGanapolsky 14年

1
INTEGERは8バイトのみを使用し、TEXTはこの例では23バイトを使用しています。これは、データを格納する型を選択する方法が明確ではありません。INTEGER型の列を作成すると、関数は自動的にUnix時間として格納されますか?
rayzinnz 2016年

2
REALも8バイトを使用します。エポック秒は2286年末まで10桁であり、IEEE は15桁から17桁の有効桁数をサポートしているため、ミリ秒よりも精度が高くなります。数値のエポックにRSQLite変換POSIXctしているようですので、私にとっては十分に機能します。
r2evans 2016

@ r2evansあなたの言っていることがよくわかりません。エポックからのミリ秒を格納したい場合、どうすればよいですか?
マイケル、

14

SQLiteの強力な機能の1つは、ストレージタイプを選択できることです。3つの異なる可能性のそれぞれの利点/欠点:

  • ISO8601文字列

    • 文字列比較により有効な結果が得られます
    • 小数秒を格納し、最大3桁の10進数
    • より多くのストレージスペースが必要
    • データベースブラウザを使用すると、その値が直接表示されます
    • 他の用途での解析の必要性
    • 「default current_timestamp」列修飾子は、この形式を使用して格納されます
  • 実数

    • 小数秒に関する高精度
    • 最長の時間範囲
  • 整数値

    • 最低の収納スペース
    • 素早い操作
    • 小さな時間範囲
    • 2038年の問題の可能性

異なるタイプを比較したり、外部アプリケーションにエクスポートしたりする必要がある場合は、必要に応じてSQLite 独自の日時変換関数を自由に使用できます。


1
なぜ2038問題があるのですか?INTEGERは64ビットストレージをサポートしているようです。
グアンボーシェン

1
@guanboshen私が知る限り、2038について心配する唯一の理由は、ホストプラットフォームでのサポートです。SQLiteのドキュメントは、リファレンス実装でC localtime_r()sqlite.org/lang_datefunc.html#caveats_and_bugs)を使用すると主張しlocaltime()ており、ホストプラットフォームが32ビットの場合、2038に対して脆弱になる可能性がありますtime_t。とはいえ、SQLiteは、外部の日付を変換前の安全な範囲(同じリンクを参照)にマッピングすることで、この可能性を防ぐと主張しているため、難解な場合を除いて、問題になることはないと思います。
ゾーイスパークス

@ZoëSparks明確にしていただきありがとうございます。
グアンボーシェン

7

実質的にすべての日付と時刻の問題について、私は物事を非常に単純なものに単純化することを好みます...整数に格納される秒まで。

整数はデータベース、フラットファイルなどで常に整数としてサポートされます。少し計算して別の型にキャストすれば、とにかく日付をフォーマットできます。

このようにすると、[現在のお気に入りのデータベースをここに挿入]が、今日選択した日付形式を誤って使用した[将来のお気に入りのデータベース]に置き換えられても心配する必要はありません。

これはほんの少しの計算オーバーヘッド(たとえば、メソッド-2秒かかります。必要に応じて要旨を投稿します)であり、日付/時刻に関する多くの操作について後で説明します。


7

タイプのフィールドに格納しlongます。見てDate.getTime()new Date(long)


どうすれば比較できますか?クエリのサンプルを教えてください..:D
Khairil Ushan

Joda Timeでコード内の比較(joda-time.sourceforge.net)を確認し、SQLで単純な長い比較(数値比較など)を使用します。
構文

aとbの間で作成されるテーブルから*を選択します。
koem 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.