簡體   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