2

我想转换一个int日期,如:

20111201

string

01DEC2011

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

4

4 回答 4

6

您可以使用 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 转换为大写即可。

于 2012-12-31T09:04:43.130 回答
3

不要在这里使用 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

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

于 2012-12-31T09:48:59.567 回答
0

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

于 2012-12-31T09:24:49.780 回答
0

老问题的新答案。此答案通过 C++11/14<chrono>库而不是 Ctmboost::date_time. 否则,它与现有答案非常相似。它需要这个免费的开源库来进行解析和格式化。

#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

或者,这些时间戳可能已知来自新西兰海岸附近的查塔姆岛,而您需要它们的 UTC 时间。只需在后面添加一行parse

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

现在输出是:

30NOV2011 19:48:57.275000

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

于 2016-04-12T01:00:58.263 回答