如何在 Windows 上获取 ISO 8601 格式的日期时间?
How to get datetime in ISO 8601 format on Windows?
使用 C++ 在 Windows 上获取 ISO8601 格式的日期时间的标准方法是什么?具体来说,我希望它的格式为:
2017-02-22T10:00:00.123-05:00
2017-02-22T10:00:00.123 >>> -05:00 <<< # how to print the offset?
我正在考虑合并 GetLocalTime
and GetTimeZoneInformation
的输出,但这看起来很深奥。在 SO 上也有类似的问题,但是,我还没有找到一个以所需格式打印 UTC 偏移量的问题。有没有更好的方法?
也许是这样的。我们调用 GetLocalTime
和 GetTimeZoneInformation
然后将其传递给 returns 格式化字符串的函数。
这是快速编写的,除了观察它 returns 在我的机器上 现在 上的正确结果外,没有经过测试。它基于 SYSTEMTIME
有一个成员 Bias
的事实,其中 UTC = Localtime + Bias
和 Bias
以分钟为单位设置。因此,通过除以 60 并取其绝对值来获得小时数。然后我们以类似的方式获取分钟并根据 Bias > 0
设置符号
#include <Windows.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
std::string format_system_time(const SYSTEMTIME& sys_time, const TIME_ZONE_INFORMATION& time_zone)
{
std::ostringstream formatted_date_time;
formatted_date_time << std::setfill('0');
formatted_date_time << sys_time.wYear << "-" << std::setw(2) << sys_time.wMonth << "-" <<
std::setw(2) << sys_time.wDay << "T" << std::setw(2) << sys_time.wHour << ":" <<
std::setw(2) << sys_time.wMinute << ":" << std::setw(2) << sys_time.wSecond << "." <<
std::setw(3) << sys_time.wMilliseconds;
//UTC = localtime + bias; bias is in minutes
int utc_offset_hours = time_zone.Bias / 60;
int utc_offset_minutes = std::abs(time_zone.Bias - (utc_offset_hours * 60));
char offset_sign = time_zone.Bias > 0 ? '-' : '+';
formatted_date_time << offset_sign << std::setw(2) << std::abs(utc_offset_hours) << ":" << utc_offset_minutes;
return formatted_date_time.str();
}
int main(int argc, char* argv[])
{
SYSTEMTIME date_and_time;
GetLocalTime(&date_and_time);
TIME_ZONE_INFORMATION time_zone;
GetTimeZoneInformation(&time_zone);
auto& formatted_date_time = format_system_time(date_and_time, time_zone);
return 0;
}
我认为 Windows 上没有适用于 c++ 的嵌入式解决方案。您可以获得的最接近的是 InternetTimeFromSystemTime
,但仅记录为支持 RFC1123。
您可能需要自己编写 GetLocalTime
+ GetTimeZoneInformation
+ wsprintf
(如果您不处理当前时间,则 GetTimeZoneInformationForYear
)。
使用Howard Hinnant's free, open-source timezone library, which works on VS-2013 and later, but does require some installation:
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
using namespace date;
auto zt = make_zoned(current_zone(), floor<milliseconds>(system_clock::now()));
cout << format("%FT%T%Ez\n", zt);
}
这只是为我输出:
2017-02-22T17:29:03.859-05:00
格式说明符 %z 为您提供文档中所述的时区偏移量(例如 MSDN on strftime),但省略了“:”。您可以像这样使用它来将“:”放入您的字符串中:
struct tm tmNow;
time_t now = time(NULL); // Get the current time
_localtime64_s(&tmNow, &now);
char bufferTime[26];
char bufferTimezoneOffset[6];
size_t tsizTime = strftime(bufferTime, 26, "%Y-%m-%dT%H:%M:%S", &tmNow); // The current time formatted "2017-02-22T10:00:00"
size_t tsizOffset = strftime(bufferTimezoneOffset, 6, "%z", &tmNow); // The timezone offset -0500
strncpy_s(&bufferTime[tsizTime], 26, bufferTimezoneOffset, 3); // Adds the hour part of the timezone offset
bufferTime[tsizTime + 3] = ':'; // insert ':'
strncpy_s(&bufferTime[tsizTime + 4], 26, &bufferTimezoneOffset[3], 3); // Adds the minutes part of the timezone offset
puts(bufferTime); // Your output: "2017-02-22T10:00:00-05:00"
我省略了毫秒,因为据我所知它们不是本地时间的一部分。
使用 C++ 在 Windows 上获取 ISO8601 格式的日期时间的标准方法是什么?具体来说,我希望它的格式为:
2017-02-22T10:00:00.123-05:00
2017-02-22T10:00:00.123 >>> -05:00 <<< # how to print the offset?
我正在考虑合并 GetLocalTime
and GetTimeZoneInformation
的输出,但这看起来很深奥。在 SO 上也有类似的问题,但是,我还没有找到一个以所需格式打印 UTC 偏移量的问题。有没有更好的方法?
也许是这样的。我们调用 GetLocalTime
和 GetTimeZoneInformation
然后将其传递给 returns 格式化字符串的函数。
这是快速编写的,除了观察它 returns 在我的机器上 现在 上的正确结果外,没有经过测试。它基于 SYSTEMTIME
有一个成员 Bias
的事实,其中 UTC = Localtime + Bias
和 Bias
以分钟为单位设置。因此,通过除以 60 并取其绝对值来获得小时数。然后我们以类似的方式获取分钟并根据 Bias > 0
#include <Windows.h>
#include <string>
#include <sstream>
#include <iomanip>
#include <cmath>
std::string format_system_time(const SYSTEMTIME& sys_time, const TIME_ZONE_INFORMATION& time_zone)
{
std::ostringstream formatted_date_time;
formatted_date_time << std::setfill('0');
formatted_date_time << sys_time.wYear << "-" << std::setw(2) << sys_time.wMonth << "-" <<
std::setw(2) << sys_time.wDay << "T" << std::setw(2) << sys_time.wHour << ":" <<
std::setw(2) << sys_time.wMinute << ":" << std::setw(2) << sys_time.wSecond << "." <<
std::setw(3) << sys_time.wMilliseconds;
//UTC = localtime + bias; bias is in minutes
int utc_offset_hours = time_zone.Bias / 60;
int utc_offset_minutes = std::abs(time_zone.Bias - (utc_offset_hours * 60));
char offset_sign = time_zone.Bias > 0 ? '-' : '+';
formatted_date_time << offset_sign << std::setw(2) << std::abs(utc_offset_hours) << ":" << utc_offset_minutes;
return formatted_date_time.str();
}
int main(int argc, char* argv[])
{
SYSTEMTIME date_and_time;
GetLocalTime(&date_and_time);
TIME_ZONE_INFORMATION time_zone;
GetTimeZoneInformation(&time_zone);
auto& formatted_date_time = format_system_time(date_and_time, time_zone);
return 0;
}
我认为 Windows 上没有适用于 c++ 的嵌入式解决方案。您可以获得的最接近的是 InternetTimeFromSystemTime
,但仅记录为支持 RFC1123。
您可能需要自己编写 GetLocalTime
+ GetTimeZoneInformation
+ wsprintf
(如果您不处理当前时间,则 GetTimeZoneInformationForYear
)。
使用Howard Hinnant's free, open-source timezone library, which works on VS-2013 and later, but does require some installation:
#include "tz.h"
#include <iostream>
int
main()
{
using namespace std;
using namespace std::chrono;
using namespace date;
auto zt = make_zoned(current_zone(), floor<milliseconds>(system_clock::now()));
cout << format("%FT%T%Ez\n", zt);
}
这只是为我输出:
2017-02-22T17:29:03.859-05:00
格式说明符 %z 为您提供文档中所述的时区偏移量(例如 MSDN on strftime),但省略了“:”。您可以像这样使用它来将“:”放入您的字符串中:
struct tm tmNow;
time_t now = time(NULL); // Get the current time
_localtime64_s(&tmNow, &now);
char bufferTime[26];
char bufferTimezoneOffset[6];
size_t tsizTime = strftime(bufferTime, 26, "%Y-%m-%dT%H:%M:%S", &tmNow); // The current time formatted "2017-02-22T10:00:00"
size_t tsizOffset = strftime(bufferTimezoneOffset, 6, "%z", &tmNow); // The timezone offset -0500
strncpy_s(&bufferTime[tsizTime], 26, bufferTimezoneOffset, 3); // Adds the hour part of the timezone offset
bufferTime[tsizTime + 3] = ':'; // insert ':'
strncpy_s(&bufferTime[tsizTime + 4], 26, &bufferTimezoneOffset[3], 3); // Adds the minutes part of the timezone offset
puts(bufferTime); // Your output: "2017-02-22T10:00:00-05:00"
我省略了毫秒,因为据我所知它们不是本地时间的一部分。