SQLite中2个日期之间的差异

96 sqlite

如何获得SQLite中两个日期之间的天数差异?我已经尝试过这样的事情:

SELECT Date('now') - DateCreated FROM Payment
Run Code Online (Sandbox Code Playgroud)

每次返回0.

Fre*_*red 106

 SELECT julianday('now') - julianday(DateCreated) FROM Payment;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,尽管函数名称可能会让人想到,但它的粒度要比天数高.这是几天,但可以是分数. (10认同)
  • 请记住,julianday返回(天数)的(小数)数量 - 即24小时,自原始日期起*中午*UTC.这通常不是你需要的,除非你碰巧住在格林威治以西12小时.例如,如果你住在伦敦,今天早上和昨天下午一样在julianday. (10认同)
  • 假设DateCreated是在当地时间,如果你做`julianday('now') - julianday(DateCreated,'utc')`,要同时生成UTC,它的工作方式与`julianday('now ','localtime') - julianday(DateCreated)`.前者不考虑DST天数,并将在3月至11月的额外时间内创建日期.后者实际上确实解释了它.http://stackoverflow.com/questions/41007455/sqlite-vs-oracle-calculating-date-differences-hours (3认同)
  • 如果您的“ DateCreated”位于UTC,则可以使用。相反,如果是当地时间,则必须将'julianday('now')`转换为当地时间。我找不到任何有此信息的地方。如果您像这篇文章一样建议执行“ julianday('now')-julianday(DateCreated)`,建议使用本地时间存储日期,则您的答案将因与GMT的偏移而被抵消,这是错误的。虽然可能不是将日期存储在本地时间的最佳做法,但它仍然可能在时区无关紧要的应用中发生(除非您使用的工具将日期强制显示在您身上)。 (2认同)

Say*_*yka 49

几天的差异

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) As Integer)
Run Code Online (Sandbox Code Playgroud)

小时差异

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) * 24 As Integer)
Run Code Online (Sandbox Code Playgroud)

几分钟的差异

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 As Integer)
Run Code Online (Sandbox Code Playgroud)

差异在秒

Select Cast ((
    JulianDay(ToDate) - JulianDay(FromDate)
) * 24 * 60 * 60 As Integer)
Run Code Online (Sandbox Code Playgroud)

  • 对于 sqlite 版本 3.12.0,强制转换表达式在括号内具有 AS TYPE。例如“选择演员表(5.6 作为整数);” https://www.sqlite.org/lang_expr.html#castexpr 否则确实有用的例子。 (2认同)
  • 这个答案比公认的答案,恕我直言,具有更多的功能。 (2认同)

Jan*_*nar 31

这两个答案都提供了解决方案,因为它们需要更复杂.假设付款已创建January 6, 2013.我们想知道这个日期和今天之间的区别.

sqlite> SELECT julianday() - julianday('2013-01-06');
34.7978485878557 
Run Code Online (Sandbox Code Playgroud)

差异是34天.我们可以使用julianday('now')更清晰.换句话说,我们不需要输入 date()或datetime()作为参数来julianday() 起作用.


con*_*r42 20

SQLite wiki是一个很好的参考,而DateAndTimeFunctions页面是一个很好的书签.记住使用sqlite命令行实用程序进行查询非常简单,这也很有帮助:

sqlite> select julianday(datetime('now'));
2454788.09219907
sqlite> select datetime(julianday(datetime('now')));
2008-11-17 14:13:55
Run Code Online (Sandbox Code Playgroud)


小智 6

只是编写时钟函数的注释。对于那些寻找工作时间的人来说,对此进行一个非常简单的更改即可将小时加分钟显示为 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
Run Code Online (Sandbox Code Playgroud)


vap*_*guy 5

这个答案有点冗长,文档不会告诉您(因为他们假设您将日期存储为UTC日期在数据库中),但是此问题的答案很大程度上取决于存储日期的时区您也不必使用Date('now'),而是使用julianday()函数来计算两个日期和一个公共日期之间的差,然后彼此减去这些结果的差。

如果您的日期存储在UTC中:

SELECT julianday('now') - julianday(DateCreated) FROM Payment;
Run Code Online (Sandbox Code Playgroud)

这是排名最高的答案,并且在文档中。如果您问我,它只是图片的一部分,并且是一个非常简单的答案。

如果您的日期存储在本地时间,使用上面的代码会让你的答案错的小时数你的GMT偏移。如果您和我一样在美国东部,即GMT -5,那么您的结果将增加5个小时。并且,如果您DateCreated因为julianday('now')违反格林尼治标准时间而尝试符合UTC :

SELECT julianday('now') - julianday(DateCreated, 'utc') FROM Payment;
Run Code Online (Sandbox Code Playgroud)

这有一个错误,它将DateCreated在夏令时(3月至11月)期间增加一个小时。假设“现在”是非DST的一天中午,并且您在6月(DST期间)中午创建了一些东西,则小时数部分将相隔1小时而不是0小时。您必须在应用程序的代码中编写一个显示结果的函数,以修改结果并从DST日期中减去一个小时。我这样做了,直到意识到有个更好的解决方案: SQLite vs. Oracle-计算日期差-小时

相反,正如我所指出的,对于本地时间存储的日期,请将两者都与本地时间匹配:

SELECT julianday('now', 'localtime') - julianday(DateCreated) FROM Payment;
Run Code Online (Sandbox Code Playgroud)

或附加'Z'到当地时间:

julianday(datetime('now', 'localtime')||'Z') - julianday(CREATED_DATE||'Z')
Run Code Online (Sandbox Code Playgroud)

这两个似乎都可以补偿并且不为DST日期添加额外的小时数,而是直接相减-因此,在DST日的正午创建的项目在非DST的正午检查时,将不会获得额外的小时。执行计算。

尽管我认识到大多数人会说不要在本地时间中将日期存储在数据库中,而要在UTC中存储日期,这样您就不会遇到这种情况,但是并不是每个应用程序都具有全世界的受众,也不是每个程序员都想要进行系统中每个日期到UTC的转换,并在他们每次在数据库中执行GET或SET时再次返回,并弄清楚是本地还是UTC。

  • @Fred 足够了。但实际上它最终带我去兜风,正如我上面描述的那样,所以对我没有帮助。我想确保将来看到这种情况的任何人都确切地知道发生了什么,因此他们不会遇到我遇到的相同陷阱 - 或者,如果他们这样做了,他们就会知道如何摆脱它们。 (3认同)

Mat*_*kas 5

如果你想要 00:00 格式的时间:我是这样解决的:

SELECT strftime('%H:%M',
                CAST((julianday(FinishTime) - julianday(StartTime)) AS REAL),
                '12:00')
FROM something;
Run Code Online (Sandbox Code Playgroud)


小智 5

鉴于您的日期格式如下:“YYYY-MM-DD HH:MM:SS”,如果您需要以月数计算两个日期之间的差异:

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


Ste*_*uan 5

首先,不清楚您的日期格式是什么。已经有一个涉及 的答案strftime("%s")。

我想扩展这个答案。

SQLite 只有以下存储类:NULL、INTEGER、REAL、TEXT 或 BLOB。为了简化事情,我假设日期是 REAL,包含自 1970 年 1 月 1 日以来的秒数。这是一个示例架构,我将为其放入“2018 年 12 月 1 日”的示例数据:

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

现在让我们计算一下“2018 年 12 月 1 日”和现在之间的日期差异(当我写这篇文章时,它是 2018 年 12 月 12 日中午):

日期相差天数:

SELECT (strftime("%s", "now") - DateCreated) / 86400.0 FROM Payment;
-- Output: 11.066875
Run Code Online (Sandbox Code Playgroud)

日期差异(以小时为单位):

SELECT (strftime("%s", "now") - DateCreated) / 3600.0 FROM Payment;
-- Output: 265.606388888889
Run Code Online (Sandbox Code Playgroud)

日期差异(以分钟为单位):

SELECT (strftime("%s", "now") - DateCreated) / 60.0 FROM Payment;
-- Output: 15936.4833333333
Run Code Online (Sandbox Code Playgroud)

日期差异(以秒为单位):

SELECT (strftime("%s", "now") - DateCreated) FROM Payment;
-- Output: 956195.0
Run Code Online (Sandbox Code Playgroud)