Interesting question (upvoted). In general, this answer can not be answered without ambiguity. And "CDT"/now is a perfect example to demonstrate this. sehe's answer does a pretty good job of it using boost/datetime. This answer provides even more detail using this free, open source timezone library.
Here's the code, then the explanation, then the output, and then comparison to sehe's answer.
#include "tz.h"
#include <string>
#include <iostream>
#include <vector>
template <class Duration>
std::vector<date::time_zone const*>
find_by_abbrev(date::sys_time<Duration> tp, const std::string& abbrev)
{
using namespace std::chrono;
using namespace date;
std::vector<time_zone const*> results;
auto& db = get_tzdb();
for (auto& z : db.zones)
{
if (z.get_info(tp).abbrev == abbrev)
results.push_back(&z);
}
return results;
}
int
main()
{
using namespace std::chrono;
using namespace date;
auto now = sys_days{2016_y/4/1} + 10h + 15min + 2s;
auto v = find_by_abbrev(now, "CDT");
for (auto zp : v)
std::cout << make_zoned(zp, now) << " " << zp->name() << '\n';
}
The strategy is to make a list of all time zones currently using "CDT" as an abbreviation. To that end a function is created which takes a std::chrono::time_point<std::chrono::system_clock, Duration>
and an abbreviation and returns a a vector<time_zone const*>
. Once found, this vector
can simply be iterated and information for each time zone can be printed out.
To implement find_by_abbrev
, then entire time zone database must be searched. Each time_zone
that uses an abbreviation abbrev
at time tp
is added to the list.
To make these results easy to compare to sehe's answer, I used the same time in my program (instead of the current time).
The program outputs:
2016-04-01 05:15:02 CDT America/Chicago
2016-04-01 06:15:02 CDT America/Havana
2016-04-01 05:15:02 CDT America/Indiana/Knox
2016-04-01 05:15:02 CDT America/Indiana/Tell_City
2016-04-01 05:15:02 CDT America/Matamoros
2016-04-01 05:15:02 CDT America/Menominee
2016-04-01 05:15:02 CDT America/North_Dakota/Beulah
2016-04-01 05:15:02 CDT America/North_Dakota/Center
2016-04-01 05:15:02 CDT America/North_Dakota/New_Salem
2016-04-01 05:15:02 CDT America/Rainy_River
2016-04-01 05:15:02 CDT America/Rankin_Inlet
2016-04-01 05:15:02 CDT America/Resolute
2016-04-01 05:15:02 CDT America/Winnipeg
2016-04-01 05:15:02 CDT CST6CDT
Now what I find especially interesting is to compare this output to sehe's answer which is based on boost/datetime:
This answer omits "America/Cancun" because it isn't currently using the abbreviation CDT, and hasn't since 2014-10-26 07:00:00 UTC.
Both answers show "America/Havana" as a potential CDT timezone, but only this answer shows that "America/Havana" alone has a UTC offset that is one hour less than all of the other candidate timezones.
Other differences continue, but with similar explanations.
This library allows you to control when/how-often you want to update your IANA database, and even offers automated downloading of the latest IANA database if your system has libcurl installed.
And using this library, I've demonstrated that "CDT/now" is not only ambiguous with respect to what IANA timezone should be chosen, but is also ambiguous as to what the current UTC offset of the chosen timezone should be. Typically to solve a problem like this, more a-priori knowledge is required, such as "I know the timestamp refers to one associated with USA" (or whatever).
But once you decide on a zone (by whatever heuristic):
auto zone = locate_zone(chosen_zone);
auto local = zone->to_local(system_clock::now());
and you've got it.
Disclaimer: Requires C++11 or better. This is a fairly modern library. It can not be ported without <chrono>
support.