Как заставить boost :: posix_time распознавать часовые пояса?

Я читаю поля меток времени из базы данных PostgreSQL. Столбец метки времени определяется как:

my_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW()

При чтении из базы данных я конвертирую ее в метку времени повышения, например:

boost::posix_time::ptime pt( boost::posix_time::time_from_string( str ) );

Кажется, проблема в том, что boost::posix_time::time_from_string() игнорирует часовой пояс.

Например:

database text string == "2013-05-30 00:27:04.8299-07"  // note -07 timezone
boost::posix_time::to_iso_extended_string(pt) == "2013-05-30T00:27:04.829900"

Когда я делаю арифметику с полученным объектом ptime, время отключается ровно на 7 часов. Что я должен сделать лучше, чтобы не потерять информацию о часовом поясе?

1

Решение

Я думаю, что вы должны использовать boost :: local_date_time, который обрабатывает часовые пояса. В документации есть пример, очень похожий на то, что вы пытаетесь сделать: http://www.boost.org/doc/libs/1_41_0/doc/html/date_time/examples.html#date_time.examples.seconds_since_epoch

РЕДАКТИРОВАТЬ: Boost поддерживает разбор дат в определенных форматах. http://www.boost.org/doc/libs/1_40_0/doc/html/date_time/date_time_io.html#date_time.format_flags

string inp("2013-05-30 00:27:04.8299-07");
string format("%Y-%m-%d %H:%M:%S%F%Q");
date d;
d = parser.parse_date(inp,
format,
svp);
// d == 2013-05-30 00:27:04.8299-07
1

Другие решения

Первоначально я задавал этот вопрос много лет назад, я даже не помню, как это делал. Но с тех пор весь код даты / времени моей базы данных на стороне клиента был значительно упрощен. Хитрость заключается в том, чтобы сообщить PostgreSQL местный часовой пояс при первом установлении соединения с БД, и позволить серверу автоматически добавлять или удалять необходимые часы / минуты, когда он отправляет обратно временные метки. Таким образом, временные метки всегда соответствуют местному времени.

Вы делаете это с одноразовым вызовом, подобным этому:

SET SESSION TIME ZONE 'Europe/Berlin';

Вы также можете использовать одно из многих сокращений часовых поясов. Например, эти две строки эквивалентны:

SET SESSION TIME ZONE 'Asia/Hong_Kong';
SET SESSION TIME ZONE 'HKT';

Полный список часовых поясов можно получить с помощью этого:

SELECT * FROM pg_timezone_names ORDER BY name;

Примечание: есть более 1000 названий часовых поясов на выбор!

У меня есть больше деталей о PostgreSQL и часовых поясах, доступных на этом посте: https://www.ccoderun.ca/programming/2017-09-14_PostgreSQL_timestamps/index.html

0