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