如何在Windows上以ISO 8601格式获取日期时间?
如何在Windows上以ISO 8601格式获取日期时间?
在Windows平台上,使用C++获取日期时间的标准方式是什么?具体地,我希望它的格式为:
2017-02-22T10:00:00.123-05:00 2017-02-22T10:00:00.123 >>> -05:00 <<< # 如何打印偏移量?
我正在研究如何将GetLocalTime
和GetTimeZoneInformation
的输出结合起来,但这看起来有点深奥。在SO上有类似的问题,但我没有找到一个以所需格式打印UTC偏移量的方法。有更好的方法吗?
在Windows上,想要以ISO 8601格式获取日期和时间并没有现成的解决方案。最接近的方法是使用InternetTimeFromSystemTime
,但它只支持RFC1123格式。
如果要在Windows上以ISO 8601格式获取日期和时间,可能需要自己编写代码,结合使用GetLocalTime
、GetTimeZoneInformation
和wsprintf
(或者如果不处理当前时间,则可以使用GetTimeZoneInformationForYear
)。
需要注意的是,GetSystemTime
返回的是UTC时间,因此不需要添加UTC偏移量。
以下是一个示例代码,展示了如何使用上述方法获取日期和时间的ISO 8601格式:
#include#include std::string GetDateTimeInISO8601Format() { SYSTEMTIME systemTime; GetLocalTime(&systemTime); TIME_ZONE_INFORMATION timeZoneInfo; GetTimeZoneInformation(&timeZoneInfo); char dateTimeBuffer[30]; sprintf(dateTimeBuffer, "%04d-%02d-%02dT%02d:%02d:%02d%03d%+03d:%02d", systemTime.wYear, systemTime.wMonth, systemTime.wDay, systemTime.wHour, systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds, -(timeZoneInfo.Bias / 60), abs(timeZoneInfo.Bias) % 60); return std::string(dateTimeBuffer); } int main() { std::string dateTime = GetDateTimeInISO8601Format(); std::cout << dateTime << std::endl; return 0; }
通过调用GetLocalTime
获取本地时间,GetTimeZoneInformation
获取时区信息,然后使用wsprintf
将获取的时间和时区信息格式化为ISO 8601格式的字符串。
运行上述示例代码,将输出当前日期和时间的ISO 8601格式表示。
在Windows上如何以ISO 8601格式获取日期时间?
也许可以像这样做。我们调用GetLocalTime
和GetTimeZoneInformation
,然后将其传递给函数,该函数返回格式化的字符串。
这个代码是快速编写的,除了观察它在我的机器上现在返回正确的结果之外,没有进行其他测试。它基于一个事实进行操作,即SYSTEMTIME
有一个成员Bias
,其中UTC = Localtime + Bias
,并且Bias
以分钟为单位设置。因此,通过除以60并取绝对值来获取小时。然后以类似的方式获取分钟,并根据Bias > 0
设置符号。
#include#include #include #include #include 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系统下,获取ISO 8601格式的日期和时间的方法不直接。解决方法是使用strftime函数来格式化时间,并手动添加时区偏移量。以下是解决方法的代码示例:
struct tm tmNow; time_t now = time(NULL); // 获取当前时间 _localtime64_s(&tmNow, &now); char bufferTime[26]; char bufferTimezoneOffset[6]; size_t tsizTime = strftime(bufferTime, 26, "%Y-%m-%dT%H:%M:%S", &tmNow); // 当前时间的格式化字符串 "2017-02-22T10:00:00" size_t tsizOffset = strftime(bufferTimezoneOffset, 6, "%z", &tmNow); // 时区偏移量的格式化字符串 -0500 strncpy_s(&bufferTime[tsizTime], 26, bufferTimezoneOffset, 3); // 添加时区偏移量的小时部分 bufferTime[tsizTime + 3] = ':'; // 插入':' strncpy_s(&bufferTime[tsizTime + 4], 26, &bufferTimezoneOffset[3], 3); // 添加时区偏移量的分钟部分 puts(bufferTime); // 输出结果: "2017-02-22T10:00:00-05:00"
此外,由于本地时间不包含毫秒,所以在代码中未添加毫秒部分。这就是问题的解决方法。