Is it possible to get time_point from zoned_time?

77 Views Asked by At

I tried to get local time / UTC selectively in std::string.

  1. What I've tried:

(1) getting std::string for UTC works fine with std::format:

auto utc = std::chrono::system_clock::now(); 
std::string sTime = std::format("{:%H%M%S}", utc);

(2) and local time:

auto zoned = std::chrono::zoned_time{ "Asia/Seoul", std::chrono::system_clock::now() }; 
sTime = std::format("{:%H%M%S}", zoned);
  1. What I want to achieve:

But they have different types. How can I achieve a functionality like this?

bool b = true;
sTime = std::format("{:%H%M%S}", b? utc : zoned);
1

There are 1 best solutions below

2
Howard Hinnant On BEST ANSWER

zoned_time has two getters:

.get_sys_time()    // get the utc time
.get_local_time()  // get the local time

It can do this because zoned_time is just a convenience data structure that holds {time_zone const*, sys_time}. If you ask it for the sys_time, it just returns what it has. If you ask it for the local_time, it uses the time_zone to change the sys_time into local_time.

And if you format a zoned_time then it formats local time.

So:

auto zoned = std::chrono::zoned_time{ "Asia/Seoul", std::chrono::system_clock::now() }; 
std::string sTime;
if (b)
    sTime = std::format("{:%H%M%S}", zoned.get_sys_time());
else
    sTime = std::format("{:%H%M%S}", zoned);

Or wrap that up in a function for a one-liner:

auto choose_time = [](bool b, auto zoned)
{
    if (b)
        return std::format("{:%H%M%S}", zoned.get_sys_time());
    return std::format("{:%H%M%S}", zoned);
};

bool b = true;
auto zoned = std::chrono::zoned_time{ "Asia/Seoul", std::chrono::system_clock::now() }; 
auto sTime = choose_time(b, zoned);

Update

@starriet주녕차 makes a good observation in a comment below that when you want local time in choose_time that zoned is "good enough" as opposed to zoned.get_local_time().

And in this particular example, the two are equivalent. However I thought it worthwhile to point out when zoned is actually a superior choice:

If the format specification asks for time zone abbreviation (%Z) or time zone offset (%z), then zoned (which has type zoned_time) has this information and can can supply it, and zoned.get_local_time() (which has type local_time) does not.

Additionally zoned.get_sys_time() can also format %Z (as "UTC") or %z (as "0000"). The type of zoned.get_sys_time() is sys_time and has the semantics of Unix Time.

Whereas local_time has the semantics of: It is a local time which has yet to be paired with a time_zone. And zoned_time is effectively that pairing.