Reputation: 18471
I´m building a C++ application that will be running in Ubuntu and will use Sqlite3 as a database.
One of my goals is to have a C++ class containing time/date fields and store then on database.
In the past I´ve used time_t
as the variable type on my class and stored them as INTEGER
type on Sqlite3, like:
C++ Class:
class MyClass {
time_t dateTimeInfo;
}
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. At the user level the time_t
is converted to ISO 8601 std::string´s
so that I can have a human readable interface.
This works very well except that it does not support 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:
C++ Class:
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:
CREATE TABLE MYCLASS (....., ???? DATETIMEINFO, ...);
My questions:
a) Is std::chrono::time_point
the correct option here ?
b) What is the Sqlite3 type equivalent ? Still an INTEGER
?
c) Is this the recommended approach (no boost
please, C++11) ?
Thanks for helping.
Upvotes: 2
Views: 2381
Reputation: 5044
Yes, std::chrono
is a very good approach (C++ internally). You can convert time points from/to milliseconds using std::chrono
like this:
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.
Comment: I don't really know much about SQLite, yet, but I found this for 64-bit types: official docs.
Upvotes: 1
Reputation: 7482
You can store the ISO 8601 string formatted times as TEXT
directly. 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:
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.
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.
Upvotes: 2