SQLiteの2つの日付の違い


110

SQLiteで2つの日付間の日数の違いを取得するにはどうすればよいですか?私はすでにこのようなことを試しました:

SELECT Date('now') - DateCreated FROM Payment

毎回0を返します。

回答:


123
 SELECT julianday('now') - julianday(DateCreated) FROM Payment;

10
関数名が何を考えているかにかかわらず、これは数日よりも細分性が高いことに注意してください。日数ですが、端数になることもあります。
lindes

10
juliandayは「端数」の「日」の数、つまり起点日の正午 UTC からの24時間を返すことに注意してください。グリニッジの12時間西に住んでいる場合を除いて、通常はそれで十分ではありません。たとえば、ロンドンに住んでいる場合、今朝は昨日の午後と同じジュリアンデーになります。
JulianSymes 2013

2
あなたDateCreatedがUTC にいる場合、それは機能します。代わりに、現地時間の場合は、現地時間に変換する必要がありますjulianday('now')。この情報がある場所はどこにも見つかりませんでした。julianday('now') - julianday(DateCreated)現地時間で保存された日付でこの投稿が提案するのが好きな場合、あなたの答えはGMTからのオフセットによってずれ、間違っているでしょう。日付を現地時間で保存することはベストプラクティスではないかもしれませんが、タイムゾーンが重要ではないアプリでも発生する可能性があります(ここで使用しているツールが強制的に日付を強制する場合を除く)。
vapcguy 16

3
DateCreatedが現地時間であるという前提で、julianday('now') - julianday(DateCreated, 'utc')両方のUTCを作成する場合、それは同じように機能しませんjulianday('now', 'localtime') - julianday(DateCreated)。前者はDST日を考慮せず、3月から11月に作成された日付に1時間追加されます。後者は実際にそれを説明します。stackoverflow.com/questions/41007455/...
vapcguy

59

日差

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)

時間の違い

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)

分単位の違い

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)

秒の違い

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)

1
sqliteバージョン3.12.0の場合、キャスト式には括弧内にAS TYPEがあります。例「Select Cast(5.6 As Integer);」sqlite.org/lang_expr.html#castexprそれ以外の場合は本当に役立つ例。
2016

@robありがとうございます。以前誰かがそのように私を編集することを提案しました。しかし、Sqlitebrowserで試したところ、機能しませんでした。古いバージョンのせいかもしれません。それがあるように、私は...それを保持
Sayka

SQLitebrowserを使用して、エラーrobを取得しました。投稿を最新の表現に編集できますか?
Noumenon 2016

@Noumenonあなたの編集を提案してください。ここでsqlitebrowserで確認し、動作する場合は、編集を確実に承認します。お時間をいただきありがとうございます。
Sayka

2
この回答は、受け入れられた回答であるIMHOよりもはるかに多くの機能を備えています。
マーカスパーソンズ

33

どちらの答えも、必要に応じて、ソリューションをもう少し複雑にします。支払いがに作成されたとしましょうJanuary 6, 2013。そして、この日付と今日の違いを知りたいのです。

sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557 

違いは34日です。julianday('now')より明確にするために使用できます。つまり、関数date()datetime()パラメータをパラメータとして配置する必要はありません julianday()


確かではありませんが、このコマンドがコード内にあり、2013年1月6日の値がデータベースからのものである場合、使用されているデータ型を検討する必要があります。
NoChance

23

SQLiteのドキュメントは優れたリファレンスであり、DateAndTimeFunctionsページはブックマークするのに適したページです。

また、sqliteコマンドラインユーティリティを使用してクエリを操作するのは非常に簡単であることを覚えておくと役立ちます。

sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55

1
このページにはGoogle検索エンジンのランキングが付いているため、現在のリンク:sqlite.org/lang_datefunc.html
markusN

9

この回答は少し時間のかかるものであり、ドキュメントはこれを通知しません(データベースに日付をUTC日付として保存していると想定しているため)。しかし、この質問への回答は、日付が保存されているタイムゾーンに大きく依存します。またDate('now')、を使用せずに、julianday()関数を使用して、両方の日付を共通の日付に対して計算し、それらの結果の差を互いに差し引きます。

日付がUTCで保存されている場合:

SELECT julianday('now') - julianday(DateCreated) FROM Payment;

これはトップランクの回答が持つものであり、ドキュメントにも記載されています。それは絵の一部にすぎず、私に尋ねれば非常に単純な答えです。

日付が現地時間で保存されている場合、上記のコードを使用すると、GMTオフセットの時間数によって回答が誤ったものになります。私のような米国東部(GMT -5)にいる場合、結果には5時間が追加されます。そして、GMTの日付に反するDateCreatedため、UTCに準拠させようとすると、次のようになりjulianday('now')ます。

SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;

これには、DateCreated夏時間(3月から11月)の間の1時間を追加するバグがあります。「今」がDST以外の日の正午で、6月に(DSTの間に)正午に何かを作成したとすると、時間の部分は0時間ではなく1時間離れた結果​​になります。結果を表示してDSTの日付から1時間を引くには、結果を表示する関数をアプリケーションのコードに記述する必要があります。:私は私が持っていたことを、その問題へのよりよい解決策があります実現するまで私は、それをした 日付の差を計算- - SQLiteの対Oracleは時間

代わりに、私に指摘されたように、現地時間で保存された日付の場合、両方を現地時間に一致させます。

SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;

または'Z'現地時間に追加:

julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')

これらは両方とも補正し、夏時間の日付に追加の時間を追加せず、直接減算しません。そのため、夏時間の正午に作成されたアイテムは、非夏時間の正午にチェックすると、追加の時間を取得しません。計算を実行します。

そして、私はほとんどの人がデータベースにローカル時間で日付を保存せず、UTCに保存してこれに遭遇しないと言うことを認識していますが、すべてのアプリケーションが世界中のオーディエンスを持っているわけではなく、すべてのプログラマが望んでいるわけではありませんシステムですべての日付をUTCに変換し、データベースでGETまたはSETを実行するたびに再び戻って、何かがローカルなのかUTCなのかを把握する。


「私に尋ねれば、それは全体像の一部であり、非常に単純な答えです。」そうだね。しかし、私の答えは、2年後にあなたの質問が来たときに彼が質問した3分後に与えられました。単純ですが、彼女は彼に似ているようでした。
Fred

1
@フレッドフェア十分。しかし、実際には、上で説明したように、実際に乗車することになり、助けにはなりませんでした。私は将来これを見ている人が何が起こっているのかを正確に知っているので、彼らが私がしたのと同じ落とし穴にぶつからないようにしたかったのです。
vapcguy 2017年

@フレッド、これは非常に良い説明であり、私は何を期待するのかわかりませんか?たぶんあなたの答えを投稿しますか?
NoChance

ご説明ありがとうございます。SQLiteの人々が、何年にもわたって受け入れられるようになり、不必要に複雑な実装になり、日付や時刻などの重要な側面でテストすることが困難になった標準に違反することを決定したかどうかはわかりません。アプリケーションのすべての日付が人間の期待どおりに機能することを確認するために必要なテストケースの数を想像してみてください。
-NoChance

3

タイムクロック関数を書くためのメモ。勤務時間を探している人にとって、これを変更するだけの非常に簡単な方法では、時間と分が60のパーセンテージとして表示されます。これは、ほとんどの給与計算会社が望んでいるためです。

CAST ((julianday(clockOUT) - julianday(clockIN)) * 24 AS REAL) AS HoursWorked

Clock In            Clock Out           HoursWorked
2016-08-07 11:56    2016-08-07 18:46    6.83333332836628

それでも、きちんとした小さなクエリ:)
vapcguy

3

00:00形式で時間を取得する場合:私はそのように解決しました:

select strftime('%H:%M',CAST ((julianday(FinishTime) - julianday(StartTime)) AS REAL),'12:00') from something

2

日付の形式が "YYYY-MM-DD HH:MM:SS"の場合、月数で2つの日付の差を見つける必要がある場合:

(strftime('%m', date1) + 12*strftime('%Y', date1)) - (strftime('%m', date2) + 12*strftime('%Y', date2))


2

まず、日付の形式が明確ではありません。を含む答えはすでにありstrftime("%s")ます。

私はその答えを詳しく述べたいと思います。

SQLiteには、NULL、INTEGER、REAL、TEXT、またはBLOBのストレージクラスしかありません。話を簡単にするために、日付は1970-01-01以降の秒を含むREALであると想定します。以下は、「2018年12月1日」のサンプルデータに含めるサンプルスキーマです。

CREATE TABLE Payment (DateCreated REAL);
INSERT INTO Payment VALUES (strftime("%s", "2018-12-01"));

次に、「2018年12月1日」と現在の日付の違いを計算します(これを書いているように、2018年12月12日正午です)。

日単位の日付の違い:

SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875

時間での日付の違い:

SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889

分単位の日付差:

SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333

秒単位の日付の違い:

SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0

2

秒単位の違いが必要な場合

SELECT strftime('%s', '2019-12-02 12:32:53') - strftime('%s', '2019-12-02 11:32:53')

0

数日の間にレコードが必要な場合は、

select count(col_Name) from dataset where cast(julianday("now")- julianday(_Last_updated) as int)<=0;

0

私の場合、差を分単位で計算するjulianday()必要があり、正確な値が得られません。代わりに、私は使用しますstrftime()

SELECT (strftime('%s', [UserEnd]) - strftime('%s', [UserStart])) / 60

両方の日付がunixtime(秒)に変換され、次に減算されて、2つの日付間の秒単位の値が取得されます。次に、それを60で割ります。

https://www.sqlite.org/cvstrac/wiki?p=DateAndTimeFunctions

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.