Cha*_*via 5 c++ datetime locale
考虑一下这个问题的后续问题.从本质上讲,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等)将输入字符串转换为a struct tm
.这似乎很容易,除了这些函数中的每一个都需要精确的迭代器范围.您无法转换"Monday,"
,必须"Monday"
完全转换,否则转换失败.因为迭代器必须是istreambuf_iterator
,你不能简单地向前扫描,因为每个增量都会改变流缓冲区中的获取位置.所以,基本上你必须首先遍历流,将每个字符复制到另一个 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);
}
Run Code Online (Sandbox Code Playgroud)
(当然,这些区域设置名称特定于 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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4998 次 |
最近记录: |