如何强制boost :: posix_time识别时区?

时间:2013-05-30 09:10:09

标签: c++ boost-date-time timestamp-with-timezone

我正在从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小时。我不应该做些什么来不丢失时区信息?

2 个答案:

答案 0 :(得分: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 :(得分:0)

很多年前,我最初问这个问题,我什至不记得这样做了。但是从那以后,我在客户端的所有数据库日期/时间代码都得到了极大的简化。技巧是告诉PostgreSQL首次建立数据库连接的时间是本地时区,并让服务器在发送回时间戳时自动添加或删除必要的小时/分钟。这样,时间戳始终位于本地时间。

您可以通过与此类似的1次通话来做到这一点:

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