如何在Windows上以ISO 8601格式获取日期时间?

22 浏览
0 Comments

如何在Windows上以ISO 8601格式获取日期时间?

在Windows平台上,使用C++获取日期时间的标准方式是什么?具体地,我希望它的格式为:

2017-02-22T10:00:00.123-05:00
2017-02-22T10:00:00.123   >>> -05:00 <<<    # 如何打印偏移量?

我正在研究如何将GetLocalTimeGetTimeZoneInformation的输出结合起来,但这看起来有点深奥。在SO上有类似的问题,但我没有找到一个以所需格式打印UTC偏移量的方法。有更好的方法吗?

0
0 Comments

在Windows上,想要以ISO 8601格式获取日期和时间并没有现成的解决方案。最接近的方法是使用InternetTimeFromSystemTime,但它只支持RFC1123格式。

如果要在Windows上以ISO 8601格式获取日期和时间,可能需要自己编写代码,结合使用GetLocalTimeGetTimeZoneInformationwsprintf(或者如果不处理当前时间,则可以使用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格式表示。

0
0 Comments

在Windows上如何以ISO 8601格式获取日期时间?

也许可以像这样做。我们调用GetLocalTimeGetTimeZoneInformation,然后将其传递给函数,该函数返回格式化的字符串。

这个代码是快速编写的,除了观察它在我的机器上现在返回正确的结果之外,没有进行其他测试。它基于一个事实进行操作,即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;
}

时区可能具有非零分钟偏移量。

现在我在查看时,我可以看到有很多,谢谢提供的信息。

编辑以考虑非零分钟偏移量。

0
0 Comments

问题的出现的原因是在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"

此外,由于本地时间不包含毫秒,所以在代码中未添加毫秒部分。这就是问题的解决方法。

0