SQLite 日期时间与 unix 时间戳的比较
Sqlite datetime comparison with a unix timestamp
Sqlite 文档states:
SQLite has no DATETIME datatype. Instead, dates and times can be stored in any of these ways:
- As a TEXT string in the ISO-8601 format. Example: '2018-04-02 12:13:46'.
- As an INTEGER number of seconds since 1970 (also known as "unix time").
...
所以我决定使用 INTEGER
unix 时间戳:
import sqlite3, time
conn = sqlite3.connect(':memory:')
conn.execute("CREATE TABLE data(datetime INTEGER, t TEXT);")
conn.execute("INSERT INTO data VALUES (CURRENT_TIMESTAMP, 'hello')")
为什么下面的查询return没有结果?
ts = int(time.time()) + 31*24*3600 # unix timestamp 1 month in the future
print(list(conn.execute("SELECT * FROM data WHERE datetime <= ?", (ts, ))))
更一般地说,如何使用 Sqlite 进行 SELECT
查询并与 unix 时间戳进行比较?
PS:
我已经阅读了SQLite DateTime comparison和类似的问题,其中提供了其他比较方法,但在这里我想准确地讨论为什么这个unix时间戳比较不起作用。
出于性能原因,我想:
- 做一个比较 整数 的查询(如果有很多行则速度非常快):
WHERE datetime <= unix_timestamp
,
- 避免将
unix_timestamp
转换成字符串,然后将 datetime
与此字符串进行比较(我想它会慢得多)
您在插入新行时使用 CURRENT_TIMESTAMP
。
这意味着在您的列中,值不会存储为 unix 时间戳,因为 CURRENT_TIMESTAMP
returns 当前日期格式为 YYYY-MM-DD hh:mm:ss
.
您可以使用函数 datetime()
和 unixepoch
修饰符将 YYYY-MM-DD hh:mm:ss
格式的 unix 时间戳转换为日期时间:
conn.execute("SELECT * FROM data WHERE datetime <= datetime(?, 'unixepoch')", (ts, ))
如果您的 unix 时间戳包含毫秒,您必须将它们去掉:
conn.execute("SELECT * FROM data WHERE datetime <= datetime(? / 1000, 'unixepoch')", (ts, ))
或者,您可以使用函数 strftime()
:
将列 datetime
中的字符串日期时间转换为 unix 时间戳
conn.execute("SELECT * FROM data WHERE strftime('%s', datetime) + 0 <= ?", (ts, ))
如果要在列中存储整数值,请像这样使用 strftime()
:
INSERT INTO data VALUES (strftime('%s', CURRENT_TIMESTAMP) + 0, 'hello')
Sqlite 文档states:
SQLite has no DATETIME datatype. Instead, dates and times can be stored in any of these ways:
- As a TEXT string in the ISO-8601 format. Example: '2018-04-02 12:13:46'.
- As an INTEGER number of seconds since 1970 (also known as "unix time").
...
所以我决定使用 INTEGER
unix 时间戳:
import sqlite3, time
conn = sqlite3.connect(':memory:')
conn.execute("CREATE TABLE data(datetime INTEGER, t TEXT);")
conn.execute("INSERT INTO data VALUES (CURRENT_TIMESTAMP, 'hello')")
为什么下面的查询return没有结果?
ts = int(time.time()) + 31*24*3600 # unix timestamp 1 month in the future
print(list(conn.execute("SELECT * FROM data WHERE datetime <= ?", (ts, ))))
更一般地说,如何使用 Sqlite 进行 SELECT
查询并与 unix 时间戳进行比较?
PS:
我已经阅读了SQLite DateTime comparison和类似的问题,其中提供了其他比较方法,但在这里我想准确地讨论为什么这个unix时间戳比较不起作用。
出于性能原因,我想:
- 做一个比较 整数 的查询(如果有很多行则速度非常快):
WHERE datetime <= unix_timestamp
, - 避免将
unix_timestamp
转换成字符串,然后将datetime
与此字符串进行比较(我想它会慢得多)
- 做一个比较 整数 的查询(如果有很多行则速度非常快):
您在插入新行时使用 CURRENT_TIMESTAMP
。
这意味着在您的列中,值不会存储为 unix 时间戳,因为 CURRENT_TIMESTAMP
returns 当前日期格式为 YYYY-MM-DD hh:mm:ss
.
您可以使用函数 datetime()
和 unixepoch
修饰符将 YYYY-MM-DD hh:mm:ss
格式的 unix 时间戳转换为日期时间:
conn.execute("SELECT * FROM data WHERE datetime <= datetime(?, 'unixepoch')", (ts, ))
如果您的 unix 时间戳包含毫秒,您必须将它们去掉:
conn.execute("SELECT * FROM data WHERE datetime <= datetime(? / 1000, 'unixepoch')", (ts, ))
或者,您可以使用函数 strftime()
:
datetime
中的字符串日期时间转换为 unix 时间戳
conn.execute("SELECT * FROM data WHERE strftime('%s', datetime) + 0 <= ?", (ts, ))
如果要在列中存储整数值,请像这样使用 strftime()
:
INSERT INTO data VALUES (strftime('%s', CURRENT_TIMESTAMP) + 0, 'hello')