当前日期和时间的字符串

102

我写了一个函数来获取当前日期和时间,格式为:DD-MM-YYYY HH:MM:SS。它能用,但是说实话,代码很丑陋。我该如何以完全相同的方式但更简单的方法实现?

string currentDateToString()
{
    time_t now = time(0);
    tm *ltm = localtime(&now);

    string dateString = "", tmp = "";
    tmp = numToString(ltm->tm_mday);
    if (tmp.length() == 1)
        tmp.insert(0, "0");
    dateString += tmp;
    dateString += "-";
    tmp = numToString(1 + ltm->tm_mon);
    if (tmp.length() == 1)
        tmp.insert(0, "0");
    dateString += tmp;
    dateString += "-";
    tmp = numToString(1900 + ltm->tm_year);
    dateString += tmp;
    dateString += " ";
    tmp = numToString(ltm->tm_hour);
    if (tmp.length() == 1)
        tmp.insert(0, "0");
    dateString += tmp;
    dateString += ":";
    tmp = numToString(1 + ltm->tm_min);
    if (tmp.length() == 1)
        tmp.insert(0, "0");
    dateString += tmp;
    dateString += ":";
    tmp = numToString(1 + ltm->tm_sec);
    if (tmp.length() == 1)
        tmp.insert(0, "0");
    dateString += tmp;

    return dateString;
}

2
http://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html - Mat
使用std::strftime会不会更简单? - Some programmer dude
Boost - 日期时间 - M456
这里有一个关于如何使用boost(如果你无法使用C++11)格式化日期时间为字符串的问题(和答案)。 - maverik
7个回答

213
自 C++11 开始,您可以使用 iomanip 标头中的 std::put_time
#include <iostream>
#include <iomanip>
#include <ctime>

int main()
{
    auto t = std::time(nullptr);
    auto tm = *std::localtime(&t);
    std::cout << std::put_time(&tm, "%d-%m-%Y %H-%M-%S") << std::endl;
}

std::put_time 是一个流操作符,因此它可以与 std::ostringstream 一起使用,将日期转换为字符串:

#include <iostream>
#include <iomanip>
#include <ctime>
#include <sstream>

int main()
{
    auto t = std::time(nullptr);
    auto tm = *std::localtime(&t);

    std::ostringstream oss;
    oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S");
    auto str = oss.str();

    std::cout << str << std::endl;
}

35
在gcc 4.9中仍然缺少std::put_time函数。 - Yuriy Petrovskiy
5
GCC 5.0 拥有此功能,但之前的版本则没有。 - ABCD
@soon 我有一个问题。在我的代码中,我有一个函数应该返回一个时间。如果一个函数返回当前时间,应该是什么返回类型? - user5447628
@ArnavBorborah,这取决于你。你可以返回Unix格式Boost本地日期时间,或创建自己的类型。 - awesoon
本地时间不是线程安全的。考虑使用 localtime_r。 - Homer6
@Homer6 这不是标准的。另请参阅:在C++20中获取当前日期/时间是否线程安全? - Ruslan

140

非C++ 11解决方案:使用<ctime>头文件,您可以使用strftime。确保您的缓冲区足够大,否则您将不希望在以后破坏它并造成混乱。

#include <iostream>
#include <ctime>

int main ()
{
  time_t rawtime;
  struct tm * timeinfo;
  char buffer[80];

  time (&rawtime);
  timeinfo = localtime(&rawtime);

  strftime(buffer,sizeof(buffer),"%d-%m-%Y %H:%M:%S",timeinfo);
  std::string str(buffer);

  std::cout << str;

  return 0;
}

3
如果缓冲区溢出了怎么办?我想strftime应该会返回一个需要在实际代码中检查的返回值,对吧? - Matthieu M.
6
对于任何给定的格式字符串,计算其可能的最大字符串长度并不需要太多思考。 - Rafael Baptista
1
我不明白为什么你可以在顶部第10行通过值传递rawtime,因为time接受一个指向time_t类型的指针:http://www.cplusplus.com/reference/ctime/time/ 在该页面上的示例中,他们以相同的方式使用了time(),这也是我不理解的。有人能解释一下吗? - Michahell
1
那里有一个 &。这意味着传递的不是 rawtime 变量的内容,而是它在内存中的地址... 这就是指针变量中存储的内容。 - max
获取毫秒数: auto now = std::chrono::system_clock::now(); std::chrono::time_pointstd::chrono::system_clock epoch; int ms = std::chrono::duration_caststd::chrono::milliseconds(now - epoch).count() % 1000; - scrutari
遗憾的是,这个函数在Windows 10上返回0,并且日期/时间格式不正确。(至少对我来说是这样)。 - SimonC

29

你可以使用 time.h 中的 asctime() 函数来简单获取一个字符串。

time_t _tm =time(NULL );

struct tm * curtime = localtime ( &_tm );
cout<<"The current date/time is:"<<asctime(curtime);

样例输出:

The current date/time is:Fri Oct 16 13:37:30 2015

3
不行:asctime不能提供问题中要求的日期/时间格式! - Aconcagua
3
虽然它不会,但它会把时间以字符串的形式呈现出来。这段代码干净而简洁。 - ABCD
5
如果代码不能提供所需的功能,即使它干净简洁也没有用。如果你想要一辆卡车(字符串),那么你就会得到一辆卡车。但如果你需要运输液体,你需要一辆罐车,而不是一辆自卸车,否则你将不会感到满意。 - Aconcagua
4
回答不错,但是asctime()函数的一个非常糟糕的设计是返回以LF结尾的字符串... - solendil
1
此外,asctime 不像 strftime 一样具有区域设置敏感性。 - Roi Danton

18

C++20中,时间点格式化(转换为字符串)可在(chrono)标准库中使用。 https://en.cppreference.com/w/cpp/chrono/system_clock/formatter

#include <chrono>
#include <format>
#include <iostream>

int main()
{
   const auto now = std::chrono::system_clock::now();
   std::cout << std::format("{:%d-%m-%Y %H:%M:%OS}", now) << '\n';
}

输出

13-12-2021 09:24:44

它在Visual Studio 2019(v16.11.5)中运行,配合最新的C++语言版本(/std:c++latest)。


1
澄清:这提供了当前的UTC时间,而OP似乎想要根据计算机当前设置的时区获取当前的本地时间。在C++20中也很容易实现。 - Howard Hinnant

7

在 MS Visual Studio 2015 (14) 中使用 C++,我使用:

#include <chrono>

string NowToString()
{
  chrono::system_clock::time_point p = chrono::system_clock::now();
  time_t t = chrono::system_clock::to_time_t(p);
  char str[26];
  ctime_s(str, sizeof str, &t);
  return str;
}

5
#include <chrono>
#include <iostream>

int main()
{
    std::time_t ct = std::time(0);
    char* cc = ctime(&ct);

    std::cout << cc << std::endl;
    return 0;
}

3
谢谢您提供的这段代码片段,它可能会提供一些有限的即时帮助。适当的解释可以大大提高其长期价值,因为它可以阐明为什么这是解决问题的好方法,并使其对于未来有类似问题的读者更具有实用性。请编辑您的答案以添加一些解释,包括您所做的假设,例如#include - Melebius
3
这实际上会返回什么? - Steve Smith
@Steve Smith 输出为: 2021年9月14日 星期二 14:17:16 - phamuc

2
我想使用C++11的解决方案,但是由于GCC 4.9不支持std::put_time,所以我不能使用它。 GCC中std::put_time的实现状态? 最终,我使用了一些C++11来稍微改进非C++11的答案。对于那些无法使用GCC 5,但仍希望在其日期/时间格式中使用一些C++11的人来说,这可能会有所帮助。
 std::array<char, 64> buffer;
 buffer.fill(0);
 time_t rawtime;
 time(&rawtime);
 const auto timeinfo = localtime(&rawtime);
 strftime(buffer.data(), sizeof(buffer), "%d-%m-%Y %H-%M-%S", timeinfo);
 std::string timeStr(buffer.data());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接