Question

I'm reading timestamp fields from a PostgreSQL database. The timestamp column is defined as:

my_timestamp TIMESTAMP WITH TIME ZONE DEFAULT NOW()

When reading from the database, I convert it to a boost timestamp like this:

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

The problem seems to be that boost::posix_time::time_from_string() ignores the timezone.

For example:

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"

When I do arithmetic with the resulting ptime object, the time is off by exactly 7 hours. Is there something better I should be doing to not lose the timezone information?

Was it helpful?

Solution 2

I originally asked this question so many years ago, I don't even remember doing it. But since then, all my database date/time code on the client side has been greatly simplified. The trick is to tell PostgreSQL the local time zone when the DB connection is first established, and let the server automatically add or remove the necessary hours/minutes when it sends back timestamps. This way, timestamps are always in local time.

You do that with a 1-time call similar to this one:

SET SESSION TIME ZONE 'Europe/Berlin';

You can also use one of the many timezone abbreviations. For example, these two lines are equivalent:

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

The full list of timezones can be obtained with this:

SELECT * FROM pg_timezone_names ORDER BY name;

Note: there are over 1000 timezone names to pick from!

I have more details on PostgreSQL and timezones available on this post: https://www.ccoderun.ca/programming/2017-09-14_PostgreSQL_timestamps/index.html

OTHER TIPS

I think you should be using boost::local_date_time, which handles time zones. There is an example in the documentation that is very similar to what you're trying to do: http://www.boost.org/doc/libs/1_41_0/doc/html/date_time/examples.html#date_time.examples.seconds_since_epoch

EDIT: Boost supports date parsing with specific formats. 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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top