2015-07-06 2 views
2

Я создаю приложение C++, которое будет работать в Ubuntu и будет использовать Sqlite3 в качестве базы данных.C++ и Sqlite3: Как сохранить дату/время с точностью до миллисекунд

Одна из моих целей - иметь класс C++, содержащий поля времени и даты, а затем хранить в базе данных.

В прошлом I've используется time_t в качестве переменной типа на моем классе и хранили их INTEGER типа на sqlite3, как:

класса C++:

class MyClass { 

     time_t dateTimeInfo; 
} 

Sqlite3:

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

Этот подход позволяет мне до SELECT раз с различными опциями сравнения (>, >=, < , <=, ==) без проблем, так как я имею дело с простым номером. На уровне пользователя time_t преобразуется в ISO 8601 std::string´s, так что я могу иметь интерфейс для чтения человеком.

Это работает очень хорошо, за исключением того, что не поддерживает миллисекунды. В моем текущем проекте мне нужно их поддерживать, поэтому мне нужно внести изменения в это.

Насколько я имел исследования я undestand мне нужно использовать std::chrono::time_point как тип класса, а именно:

C++ Класс:

class MyClass { 

     std::chrono::time_point dateTimeInfo; 
} 

Но я действительно не знаю, какой тип данных использовать в sqlite3 и если он будет работать так же, как time_t используется для ...

sqlite3:

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

Мои вопросы:

а) Является ли std::chrono::time_point правильный вариант здесь?

b) Что такое эквивалент Sqlite3? Еще INTEGER?

c) Это рекомендуемый подход (нет boost, пожалуйста, C++ 11)?

Спасибо за помощь.

+1

Вы можете сохранить формат ISO 8601 непосредственно в виде строки и сравнить его с обычными операторами сравнения, если ваши строки сравнения также отформатированы по ISO. Вы пытались это сделать? – huu

ответ

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.

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 на выходе, когда вы взаимодействуете с этой базой данных, которая является wh в любом случае вы на стороне клиента.

Этот метод использует тот факт, что в пределах часового пояса лексикографическое упорядочение строк дает семантически правильное упорядочение datetimes. Если ваш сценарий использования включает несколько часовых поясов, использование одного часового пояса, такого как время UTC, для хранения в базе данных помогает сохранить это свойство заказа.

+0

Он видит, что этот подход имеет проблемы с часовыми поясами: оба: SELECT * FROM tbl WHERE ts> '2015-07-06T10: 59: 46.1234-03: 00'; 'и' SELECT * FROM tbl WHERE ts> '2015- 07-06T10: 59: 46.1234-05: 00 '; 'возвращает' second' и 'third', и это не ожидаемое поведение ... – Mendes

+0

Вы абсолютно правы, ISO 8601 лексикографически упорядочен в часовых поясах, а не между , Чтобы получить чистое упорядочение, вы должны хранить строки даты и времени как время UTC. Я объясню это в своем ответе с помощью редактирования. – huu

Смежные вопросы