【问题标题】:is this a bug in std::get_time?这是 std::get_time 中的错误吗?
【发布时间】:2015-11-08 05:59:34
【问题描述】:

我正在尝试解析日期时间字符串并将结果放入 std::tm 结构中。下面是代码,

#include <iomanip>
#include <ctime>
#include <sstream>
#include <string>

std::stringstream ss;
struct std::tm when;

ss.str("8/14/2015 3:04:23 PM");
ss >> std::get_time(&when, "%m/%d/%Y %r");

运行代码后,when.tm_hour 为 27。这是一个错误,还是我做错了什么?

我在 Windows 7 上使用 Visual Studio 2013。

谢谢。

【问题讨论】:

  • 很奇怪,我根本无法让它在 g++ 中工作,而且 Ideone 无法解析基本日期和时间。我很好奇这里发生了什么。
  • Clang/libc++ 说 15. GCC/libstdc++ 无法解析。这很有趣。
  • 尝试在get_time 之前注入不同的语言环境。即ss.imbue(std::locale("en_US"));我不确定Windows支持哪些语言环境,或者它是否期望en-USen_US。您可能需要四处寻找。
  • 正常使用将涉及在流式传输之前使用ss.imbue(std::locale(&lt;something&gt;))。由于操作可能会失败,请在打印when.tm_hour之前检查ss.fail()
  • 看起来这个问题是由字符串中的“PM”引起的。如果它更改为“AM”,则一切正常。开发者是否添加了 24 而不是 12?

标签: c++ c++11


【解决方案1】:

您在 Microsoft 的 std::num_get::do_get 函数实现中遇到了一个错误,特别是在部分时间解析 AM/PM (%p) 的部分:

    case 'p':
        _Ans = _Getloctxt(_First, _Last, (size_t)0, ":AM:am:PM:pm");
        if (_Ans < 0)
            _State |= ios_base::failbit;
        else
            _Pt->tm_hour += _Ans * 12;
        break;

问题是 _Getloctxt 返回一个 int 范围 [0,3] 而不是预期范围 [0,1]。

此错误已报告给声称已在 Visual Studio 2015 中修复的 Microsoft (ID:808162)。

【讨论】:

  • 看来AmPm 也可能会失败,因为它似乎区分大小写。
  • 好点。使用AmPm 会导致设置流failbit 。具有讽刺意味的是,与am 不同,使用Am 实际上会导致设置正确的时间。
  • 谢谢安德鲁,回答了我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 2021-09-06
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 2018-03-09
相关资源
最近更新 更多