I want to get a timestamp in the format "YYYY-MM-DD hh::mm::ss.fff +zz".
I thought I could do this with the %z
specifier for std::format
but I'm getting this error on 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;
}
If I use "{:%F %T}"
as the format string, it works fine (but obviously does not include the time zone). This tells me that the error message is nonsensical, but is there some way around this? Is this a bug in the compiler?
For posterity, here's a workaround using good old 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();
}
current_zone()->to_local(now)
but ratherzoned_time(current_zone(), now)
, which does work with that specifier. – Adapt