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

时间:2015-07-06 14:43:45

标签: c++ c++11 sqlite chrono

我正在构建一个将在Ubuntu中运行的C ++应用程序,并将使用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,以便我可以拥有人类可读的界面。

这非常有效,除了它不支持millisecods 。在我目前的项目中,我需要支持它们,所以我需要对此进行更改。

到目前为止,我没有学习,我需要使用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)这是推荐的方法(请{C} 11,不是boost?)

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

您可以直接将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时间)在数据库中存储有助于保留此排序属性。

答案 1 :(得分:1)

是的,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位整数类型将其与SQLite一起存储,因为数据可能超过32位。

评论:我对SQLite并不是很了解,但我发现64位类型:official docs