【问题标题】:C++ convert date formatsC++ 转换日期格式
【发布时间】:2012-12-15 11:47:52
【问题描述】:

我想将int 日期转换为:

20111201

string:

2011 年 12 月 1 日

C++ 中是否有内置的快速日期格式转换(或者我可以执行的 bash 系统命令)来执行此操作,或者我是否在所有月份都无法进行切换?

【问题讨论】:

    标签: c++ date format data-conversion


    【解决方案1】:

    您可以使用 strptime 将字符串转换为 struct tm,然后使用 strftime 重新格式化:

    #include <ctime>
    #include <iostream>
    #include <sstream>
    
    int main()
    {
      std::ostringstream date1;
      date1 << 20111201;
    
      struct tm tm;
      strptime(date1.str().c_str(), "%Y%m%d", &tm);
    
      char date2[10];
      strftime(date2, sizeof(date2), "%d%b%Y", &tm);
    
      std::cout << date1.str() << " -> " << date2 << std::endl;
    }
    

    输出是:

    20111201 -> 01Dec2011
    

    如果需要,只需将 Dec 转换为大写即可。

    【讨论】:

    • 日期以 int 形式给出,因此可以使用 int-string 转换来更新答案。
    • 好了,现在从 int 进行转换。
    • strptime 不是标准函数。
    • @JamesKanze man strptime 声称“符合 SUSv2,POSIX.1-2001”,并且问题指定使用 bash 作为解决方案运行系统命令,所以...
    • @hyde 我认为他的意思是它不是 C++ 标准(或 C 的一部分)
    【解决方案2】:

    不要在这里使用 bash。可行的方法是在 C++ 中使用 Boost 的原因比我在这里列出的时间要多,但最终它将与您遇到的大多数其他解决方案一样快,除非您的功能绝对是时间关键的,否则它不会反正不会有很大的不同。

    此外,它比您经常遇到的那些糟糕的、硬编码的小日期转换例程更加灵活和可维护。

    下面的代码会做你想做的事。

    #include <iostream>
    #include <sstream>
    
    #include <boost/date_time/gregorian/gregorian.hpp>
    #include <boost/algorithm/string.hpp>
    
    using namespace boost::gregorian;
    using namespace std;
    
    int main(int argc, char **argv)
    {
        int dateIn = 20111201;
    
        // Read the date in from ISO format as an int.
        ostringstream ss;
        ss << dateIn;
        date d(from_undelimited_string( ss.str() ));
    
        // Set the output format
        date_facet *fct = new date_facet("%d%b%Y");    // [1]
        locale loc = locale(locale::classic(), fct);
    
        // Render the date as a string;
        ss.str("");
        ss.imbue(loc);
        ss << d;
        string dateOut( ss.str() );
        boost::to_upper( dateOut );
    
        cout << dateOut << endl;
    }
    

    这给出了以下输出:

    01DEC2011
    

    只需在 ref [1] 处更改格式字符串 "%d%b%Y" 将更改为不同的输出格式,但请记住我也已将其转换为大写。

    【讨论】:

    • 我很高兴看到有人终于知道如何正确组合这个 boost date_time 的东西,谢谢,+1。 :) 它仍然比应有的复杂得多。 :(
    【解决方案3】:

    没有直接内置的,因为这种日期格式 比较少见。这里最简单的解决方案是 使用%/ 将日期分解为年月日 运算符(例如月份是value / 100 % 100),然后格式化 通常使用三个值,使用std::ostream,并查找 表中的日期。 (这显然需要一些错误 检查,因为并非所有整数值都会产生有效日期。)

    【讨论】:

      【解决方案4】:

      旧问题的新答案。此答案通过 C++11/14 &lt;chrono&gt; 库而不是 C 的 tmboost::date_time 传输。否则,它与现有答案非常相似。它需要这个free, open-source library 进行解析和格式化。

      #include "tz.h"
      #include <iostream>
      #include <locale>
      #include <sstream>
      
      int
      main()
      {
          auto date1 = 20111201;
      
          std::stringstream stream;
          stream.exceptions(std::ios::failbit);
          stream << date1;
      
          std::chrono::system_clock::time_point tp;
          date::parse(stream, "%Y%m%d", tp);
      
          auto str = date::format("%d%b%Y", tp);
      
          auto& ct = std::use_facet<std::ctype<char>>(std::locale::classic());
          ct.toupper(&str.front(), &str.back()+1);
          std::cout << str << '\n';
      }
      

      我已包含 stream.exceptions(std::ios::failbit); 以嘈杂地检测无效的“整数日期”。我已经包含了旧的 C++98 代码来将字符串转换为大写(最后是 locale 舞蹈)。

      01DEC2011
      

      使用现代 C++ 日期/时间库的优点之一是可以轻松进行更改。例如,如果现在您需要解析时间戳而不是天精度,而是毫秒精度怎么办?以下是可能的做法:

      auto date1 = 20111201093357.275L;
      
      std::stringstream stream;
      stream.exceptions(std::ios::failbit);
      stream << std::fixed << date1;
      
      std::chrono::system_clock::time_point tp;
      date::parse(stream, "%Y%m%d%H%M%S", tp);
      
      auto str = date::format("%d%b%Y %T", tp);
      
      auto& ct = std::use_facet<std::ctype<char>>(std::locale::classic());
      ct.toupper(&str.front(), &str.back()+1);
      std::cout << str << '\n';
      

      哪个输出:

      01DEC2011 09:33:57.275000
      

      或者这些时间戳可能已知来自Chatham Island off the coast of New Zealand,而您需要它们的UTC。只需在parse 后面加一行:

      tp = date::locate_zone("Pacific/Chatham")->to_sys(tp);
      

      现在输出是:

      30NOV2011 19:48:57.275000
      

      考虑到任意时区和亚秒级精度目前超出了所有其他 C++ 库的能力。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-24
        • 2017-12-23
        相关资源
        最近更新 更多