2

我正在从 PostgreSQL 数据库中读取时间戳字段。时间戳列定义为:

my_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW()

从数据库读取时,我将其转换为像这样的 boost 时间戳:

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 小时。为了不丢失时区信息,我应该做些什么更好的事情?

4

2 回答 2

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
于 2013-05-30T09:14:48.070 回答
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

于 2018-09-14T22:57:03.437 回答