c++和Sqlite3:如何以毫秒精度存储日期/时间

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

本文关键字:精度 存储 日期 时间 Sqlite3 c++      更新时间:2023-10-16

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

我的目标之一是有一个c++类包含时间/日期字段,并将其存储在数据库中。

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

c++类:

class MyClass {
        time_t dateTimeInfo;
}

Sqlite3:

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

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

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

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

c++类:

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) ?

您可以直接将ISO 8601字符串格式化的时间存储为TEXT。例如,您可以制作以下表格:

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时间)进行存储有助于保持这种排序属性。

是的,std::chrono是一个非常好的方法(c++内部)。您可以使用std::chrono将时间点从/转换为毫秒,如下所示:

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位整型来存储它,因为数据可以超过32位。

注释:我不是很了解SQLite,但我发现这是64位类型的:官方文档。