Desired Output:
I want to get a timestamp in the format “YYYY-MM-DD hh::mm::ss.fff +zz”.
I attempted to use the %z
specifier for std::format
from cppreference.com, but this caused the following error in MSVC:
error C7595: 'std::basic_format_string<char,const std::chrono::time_point<
std::chrono::local_t,std::chrono::duration<std::chrono::system_clock::rep,std::chrono::system_clock::period>> &>::basic_format
_string': call to immediate function is not a constant expression
#include <chrono>
#include <format>
#include <iostream>
std::string get_current_time_and_date() {
auto const time =
std::chrono::current_zone()->to_local(std::chrono::system_clock::now());
return std::format("{:%F %T %z}", time);
}
int main() {
std::cout << get_current_time_and_date() << "\n";
return 0;
}
Using the format string "{:%F %T}"
works, but does not include the time zone. This suggests that the error message is nonsensical. Is there a way to work around this issue, or is it a compiler bug?
Workaround
For posterity, here’s a workaround using strftime
:
std::string get_current_time_and_date() {
auto time = std::chrono::system_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
time.time_since_epoch()) %
1000;
auto localT = std::chrono::system_clock::to_time_t(time);
std::tm timeStruct;
localtime_s(&timeStruct, &localT);
std::ostringstream oss;
const size_t TIME_STR_LEN = 32;
char buf[TIME_STR_LEN];
std::strftime(buf, TIME_STR_LEN, "%F %T", &timeStruct);
char timezonebuf[16];
std::strftime(timezonebuf, sizeof(timezonebuf), " %z", &timeStruct);
oss << buf << '.' << std::setfill('0') << std::setw(3) << ms.count() << timezonebuf;
return oss.str();
}
This workaround provides a timestamp in the format “YYYY-MM-DD hh::mm::ss.fff +zz”.