简体   繁体   English

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

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

I´m building a C++ application that will be running in Ubuntu and will use Sqlite3 as a database. 我正在构建一个将在Ubuntu中运行的C ++应用程序,并将Sqlite3用作数据库。

One of my goals is to have a C++ class containing time/date fields and store then on database. 我的目标之一是拥有一个包含时间/日期字段的C ++类,然后将其存储在数据库中。

In the past I´ve used time_t as the variable type on my class and stored them as INTEGER type on Sqlite3, like: 过去,我在类中使用time_t作为变量类型,并将它们作为INTEGER类型存储在Sqlite3中,例如:

C++ Class: C ++类:

class MyClass {

        time_t dateTimeInfo;
}

Sqlite3: SQLITE3:

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

That approach allows me to SELECT times with different comparasion operatiors ( >, >=, < , <=, == ) with no problems at all, as I´m dealing with simple number. 这种方法使我可以SELECT具有不同比较运算符( >, >=, < , <=, == )的SELECT时间,完全没有问题,因为我正在处理简单数字。 At the user level the time_t is converted to ISO 8601 std::string´s so that I can have a human readable interface. 在用户级别, time_t转换为ISO 8601 std::string´s因此我可以拥有一个人类可读的界面。

This works very well except that it does not support millisecods . 除了不支持millisecods之外, 非常有效。 In my current project I need to support them, so I need to make changes to this. 在我当前的项目中,我需要支持他们,因此需要对此进行更改。

As far I had studies I undestand I need to use std::chrono::time_point as the class type, as follows: 就我所学的知识而言,我需要使用std::chrono::time_point作为类类型,如下所示:

C++ Class: C ++类:

class MyClass {

        std::chrono::time_point dateTimeInfo;
}

But I really don´t know what data type to use in Sqlite3 and if it will work the same way time_t used to... 但是我真的不知道在Sqlite3中使用哪种数据类型,以及它是否能像time_t一样工作。

Sqlite3: SQLITE3:

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

My questions: 我的问题:

a) Is std::chrono::time_point the correct option here ? a) std::chrono::time_point在这里是正确的选项吗?

b) What is the Sqlite3 type equivalent ? b)什么是Sqlite3类型等效项? Still an INTEGER ? 还是INTEGER

c) Is this the recommended approach (no boost please, C++11) ? c)本是推荐的方法(无boost请,C ++ 11)?

Thanks for helping. 感谢您的帮助。

You can store the ISO 8601 string formatted times as TEXT directly. 您可以将ISO 8601字符串的格式化时间直接存储为TEXT For instance, you can make the following table: 例如,您可以制作下表:

CREATE TABLE tbl(name TEXT, ts TEXT);

and insert ISO 8601 formatted strings with millisecond values as a text string: 以毫秒值插入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');

At this point you can query them using comparison operators: 此时,您可以使用比较运算符查询它们:

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

As an added bonus, you get ISO 8601 formats on the way out when you interface with this database, which is what you're doing on the client side anyway. 作为额外的好处,当您与此数据库进行交互时,您将获得ISO 8601格式的输出,无论如何,这都是您在客户端执行的操作。

This method makes use of the fact that within a timezone, the lexicographic ordering of the strings produces a semantically correct ordering of datetimes. 此方法利用以下事实:在时区中,字符串的字典顺序产生语义上正确的日期时间顺序。 If your usage scenario involves multiple timezones, using a single timezone, such as UTC time, for storage within the database helps preserve this ordering property. 如果您的使用方案涉及多个时区,则使用单个时区(例如UTC时间)在数据库中进行存储将有助于保留此排序属性。

Yes, std::chrono is a very good approach (C++ internally). 是的, std::chrono是一种非常好的方法(内部为C ++)。 You can convert time points from/to milliseconds using std::chrono like this: 您可以使用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();

In this case you should use an 64-bit integral type to store it with SQLite because the data can exceed 32 bits. 在这种情况下,您应该使用64位整数类型将其与SQLite一起存储,因为数据可能超过32位。

Comment: I don't really know much about SQLite, yet, but I found this for 64-bit types: official docs . 评论:到目前为止,我对SQLite的了解并不多,但是我发现这适用于64位类型: Official docs

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM