我正在尝试从文本文件中解析日期时间。时间戳的精度为微秒,但是由于历史原因,超出了我的控制范围,因此它们是使用冒号而不是点来创建的,以分隔小数秒部分,例如:

2015/05/05 03:10:43:537408

代替
2015/05/05 03:10:43.537408

我可以使用以下代码解析这些时间戳,而无需保留小数秒:
#include <iostream>
#include <sstream>
#include <boost/date_time.hpp>
namespace bt = boost::posix_time;

const std::string inputString = "2015/05/05 03:10:43:537408";
const std::string inputFormat = "%Y/%m/%d %H:%M:%S%F";

bt::time_input_facet * facet = new bt::time_input_facet(inputFormat);
const std::locale loc(std::locale::classic(), facet);

std::istringstream iss(inputString);
iss.imbue(loc);
boost::posix_time::ptime pt;
iss >> pt;

您可能会猜到,使用小写的-f分数秒格式化程序会导致解析失败(pt保持非日期时间)。另外,在格式字符串中插入冒号也无济于事:
const std::string inputFormat = "%Y/%m/%d %H:%M:%S:%F";

Boost似乎可以推断出点分隔符。

除了显式检查冒号分隔符并以不同的方式处理它外,有人知道是否有可能使用boost库来解析此非标准时间格式?

最佳答案

没有内置的方式。

time_facet get函数假定'.'为分隔符:

    case 'f':
      {
        // check for decimal, check SV if missing
        if(*sitr == '.') {
          ++sitr;
          parse_frac_type(sitr, stream_end, frac);
          // sitr will point to next expected char after this parsing
          // is complete so no need to advance it
          use_current_char = true;
        }
        else {
          return check_special_value(sitr, stream_end, t, c);
        }
        break;
      }
    case 'F':
      {
        // check for decimal, skip if missing
        if(*sitr == '.') {
          ++sitr;
          parse_frac_type(sitr, stream_end, frac);
          // sitr will point to next expected char after this parsing
          // is complete so no need to advance it
          use_current_char = true;
        }
        else {
          // nothing was parsed so we don't want to advance sitr
          use_current_char = true;
        }
        break;
      }

您可以修改实现(例如Format a posix time with just 3 digits in fractional seconds)或子类并覆盖相关的成员函数。

不管是因为该类不是为继承而设计的,都会有点烦人。

我个人认为格式字符串仅指示小数设置而没有任何分隔符,因此您确实可以在格式规范中包括:

07-24 09:46
查看更多