C++ 和 Sqlite3:如何以毫秒精度存储 date/time

C++ and Sqlite3: How to store date/time with milliseconds precision

我正在构建一个 C++ 应用程序,它将在 Ubuntu 中 运行 并将使用 Sqlite3 作为数据库。

我的目标之一是拥有一个包含 time/date 字段的 C++ class 然后存储在数据库中。

过去我在 class 上使用 time_t 作为变量类型,并在 Sqlite3 上将它们存储为 INTEGER 类型,例如:

C++ Class:

class MyClass {

        time_t dateTimeInfo;
}

Sqlite3:

CREATE TABLE MYCLASS (....., INTEGER DATETIMEINFO, ...);

这种方法让我可以 SELECT 次使用不同的比较运算符 (>, >=, < , <=, ==) 而完全没有问题,因为我处理的是简单的数字。在用户级别 time_t 被转换为 ISO 8601 std::string´s 这样我就可以拥有一个人类可读的界面。

除了它不支持毫秒外,它工作得很好。在我目前的项目中,我需要支持他们,所以我需要对此进行更改。

据我了解,我需要使用 std::chrono::time_point 作为 class 类型,如下所示:

C++ Class:

class MyClass {

        std::chrono::time_point dateTimeInfo;
}

但我真的不知道在 Sqlite3 中使用什么数据类型以及它是否会像 time_t 以前那样工作...

Sqlite3:

CREATE TABLE MYCLASS (....., ???? DATETIMEINFO, ...);

我的问题:

a) std::chrono::time_point 是正确的选项吗?

b) 等效的 Sqlite3 类型是什么?还是 INTEGER ?

c) 这是推荐的方法吗(请不要 boost,C++11)?

感谢您的帮助。

是的,std::chrono 是一个很好的方法(C++ 内部)。您可以使用 std::chrono 转换时间点 from/to 毫秒,如下所示:

using namespace std::chrono;

typedef time_point<system_clock, milliseconds> time_points_millis;

time_points_millis tp = system_clock::now();

// An at least 43 bit signed integral type
auto epoch = tp.time_since_epoch();

在这种情况下,您应该使用 64 位整数类型将其与 SQLite 一起存储,因为数据可以超过 32 位。

评论:我对 SQLite 还不是很了解,但是我发现它适用于 64 位类型:official docs.

您可以将 ISO 8601 字符串格式的时间直接存储为 TEXT。例如,您可以进行以下 table:

CREATE TABLE tbl(name TEXT, ts TEXT);

并插入 ISO 8601 格式的字符串 和毫秒值 作为文本字符串:

INSERT INTO tbl VALUES ('first', '2015-07-06T10:59:46.1234Z');
INSERT INTO tbl VALUES ('second', '2015-07-06T10:59:47.5678Z');
INSERT INTO tbl VALUES ('third', '2015-07-06T10:59:48.9012Z');

此时您可以使用比较运算符查询它们:

SELECT * FROM tbl WHERE ts <= '2015-07-06T10:59:46.1233Z';
// Returns nothing
SELECT * FROM tbl WHERE ts <= '2015-07-06T10:59:46.1234Z';
// Returns the first record
SELECT * FROM tbl WHERE ts > '2015-07-06T10:59:46.1234Z';
// Returns the last two records

作为额外的好处,当您与此数据库交互时,您将获得 ISO 8601 格式,无论如何,这就是您在客户端所做的。

此方法利用了这样一个事实,即在时区内,字符串的字典顺序会产生语义上正确的日期时间顺序。如果您的使用场景涉及多个时区,使用单个时区(例如 UTC 时间)存储在数据库中有助于保持这种顺序 属性.