我正在构建一个将在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
?)
感谢您的帮助。
答案 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。