How do you get the timezone (offset) for a location on a particular date?

匿名 (未验证) 提交于 2019-12-03 01:22:02

问题:

I am storing messages in UTC. Therefore, if someone looks back to a previous message, I need to be able to convert the timestamp to what the time was relative to what the timezone was then. How do I get what the timezone was then?

For example, on September 3, 2012 the timezone is PDT. The current time offset is -0700. I send a message at 9:06. The time UTC is 16:06.

I come back to this message December 1, 2012. The current timezone is PST. The current time offset is -0800. I look at the message I sent on September 3, 2012. If I were to convert back from UTC using the current time offset I get 8:06 which is NOT when the message was sent. It was sent at 9:06.

Therefore, I need a way to find out that on September 3, 2012 the timezone was PDT, not PST.

P.S. without libraries would be the best, thanks.

回答1:

Boost Date_time does that, here is simply example I had hanging around (code below):

edd@max:~/src/progs/C++$ g++ -o boost_posix_time_dst boost_posix_time_dst.cpp edd@max:~/src/progs/C++$ ./boost_posix_time_dst  DST ran from 2012-Mar-11 02:00:00 to 2012-Nov-04 02:00:00 DST shortcut PDT DST name     Pacific Daylight Time edd@max:~/src/progs/C++$  

There is also functionality to form a date (your Dec 1, 2012) and see if it is inside a give interval (as formed here by the DST start and end).

I think you can also get it by forming a date and checking the isDST() boolean.

My short program is below. You need a local copy of the csv file which is a) in the Boost sources and b) on a number of sites dealing with timezones (eg Google's first or second hit finds it at CERN):

#include <iostream> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/date_time/posix_time/posix_time_io.hpp> #include <boost/date_time/gregorian/gregorian.hpp>   #include <boost/date_time/local_time/local_time.hpp>       using namespace boost::posix_time; using namespace boost::gregorian;  int main(int argc, char **argv) {    boost::local_time::tz_database tz;   tz.load_from_file("/tmp/date_time_zonespec.csv");    boost::local_time::time_zone_ptr tzp =             tz.time_zone_from_region("America/Los_Angeles");        int year = 2012;   boost::posix_time::ptime t1 = tzp->dst_local_start_time(year);   boost::posix_time::ptime t2 = tzp->dst_local_end_time(year);   std::cout << "DST ran from " << t1 << " to " << t2 << std::endl;   std::cout << "DST shortcut " << tzp->dst_zone_abbrev() << std::endl;   std::cout << "DST name     " << tzp->dst_zone_name() << std::endl;  } 


回答2:

If it's a simple C++ application that doesn't require the use of separate time-zones during execution then you can simply use localtime to get a shared struct tm * reference that contains timezone information for a particular time_t that it is called with. If you system is configured with a timezone of PST, then when you invoke localtime, then it will use the pacific timezone information for the display - an example using Jan 1, 2012 (GMT) and June 1, 2012:

time_t def_time = 1325376000; struct tm *a_tim = localtime(&def_time); printf("%s %ld %d\n", a_tim->tm_zone, a_tim->tm_gmtoff, a_tim->tm_isdst); def_time = 1338505200; a_tim = localtime(&def_time); printf("%s %ld %d\n", a_tim->tm_zone, a_tim->tm_gmtoff, a_tim->tm_isdst); 

On my system (TZ=Europe/Dublin) this displays:

GMT 0 0 IST 3600 1 

By overriding the TZ environment variable with America/Los_Angeles I get:

PST -28800 0 PDT -25200 1 

i.e. the system is well able to determine the timezone name, offset from GMT and if summer time is in effect from the UTC timestamp.

Edit: trying to use multiple timezones within C/C++ programs simultaneously using the posix supplied timezone routines is horrible, and I would definitely recommend using boost if you're in that situation as it's a quick solution.



回答3:

Just knowing the current offset isn't enough to tell you the offset for the same location at another time of year; there are plenty of pairs of locations that share a timezone for only part of the year (e.g. Central Europe and Algeria, or the eastern US and Colombia).

The simplest fix would be to store the timezone along with the message.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!