繁体   English   中英

C ++:将日期/时间字符串转换为tm结构

[英]C++ : convert date/time string to tm struct

考虑一下这个问题的后续问题 从本质上讲,C ++日期/时间格式化设施似乎无可救药地被打破 - 以至于为了做一些简单的事情,如将日期/时间字符串转换为对象,你真的不得不求助于Boost.Datetime或者旧的C strftime / strptime设施。

问题是这些解决方案都不能直接使用嵌入特定iostream对象的C ++语言环境设置。 C工具使用全局C / POSIX语言环境设置,而Boost.Datetime中的I / O工具似乎完全绕过iostream语言环境设置,允许用户直接设置月份,工作日等的名称,而不管语言环境如何。

因此,我想要一些能够尊重特定I / O流上的语言环境设置的东西,这些设置允许我将字符串转换为struct tm 这似乎很容易,但我遇到了各个角落的障碍。 起初,我注意到STL的一些实现提供了非标准的std::time_get::get函数,所以我决定实现类似的东西。 基本上,我只是迭代格式字符串,每当我点击格式标志时,我会使用time_get工具之一(如get_monthname,get_weekday,get_year等)将输入字符串转换为struct tm 这似乎很容易,除了这些函数中的每一个都需要精确的迭代器范围。 你不能转换"Monday," ,它必须完全是"Monday" ,否则转换失败。 由于迭代器必须是istreambuf_iterator ,因此不能简单地向前扫描,因为每个增量都会更改流缓冲区中的get位置。 所以,基本上你必须首先遍历流,将每个字符复制到另一个 streambuffer,然后当你点击分隔符(如空格或逗号)时,使用带有time_get工具的第二个streambuffer。 这就好像C ++设计师竭尽全力让它尽可能地烦人。

那么,有更简单的解决方案吗? 大多数C ++程序员在需要将日期/时间字符串转换为对象时会做什么? 我们是否只需要使用C设施,并且失去了在不同的iostream对象上出现的不同区域设置所带来的优势?

Boost默认使用标准语言环境; 你不必绕过任何东西:

#include "boost/date_time/gregorian/gregorian.hpp"
#include <iostream>
#include <sstream>
#include <ctime>

int main(){
  using namespace boost::gregorian;

  std::locale::global(std::locale(""));
  std::locale german("German_Germany");
  std::locale french("French_France");

  date d1(day_clock::local_day());
  date d2;
  std::stringstream ss("2002-May-01");

  std::cout << "Mine: " << d1 << " | ";
  ss >> d2;
  std::cout << d2 << '\n';

  std::cout.imbue(german);
  std::cout << "Germany: " << d1 << " | ";
  ss.imbue(german);
  ss << "2002-Mai-01";
  ss >> d2;
  std::cout << d2 << '\n';

  std::cout.imbue(french);
  std::cout << "France: " << d1 << " | " << d2 << '\n';

  std::tm t = to_tm(d1);
  std::cout << "tm: " << asctime(&t);
}

(当然,这些区域设置名称特定于Windows。)输出:

Mine: 2010-Oct-28 | 2002-May-01
Germany: 2010-Okt-28 | 2002-Mai-01
France: 2010-oct.-28 | 2002-mai-01
tm: Thu Oct 28 00:00:00 2010

为什么不使用C库? 它几乎可以在您的实现中使用,并且经过良好的调试和测试。

如果它缺少某些功能,肯定会更容易制作包装功能,这样可以实现您想要的时区工作。

我总是尝试使用与语言环境无关的字符串来序列化数据。 让生活更轻松。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM