99

I wrote a function to get a current date and time in format: DD-MM-YYYY HH:MM:SS. It works but let's say, its pretty ugly. How can I do exactly the same thing but simpler?

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;
}
awesoon
  • 32,469
  • 11
  • 74
  • 99
Katie
  • 3,517
  • 11
  • 36
  • 49
  • 2
    http://pubs.opengroup.org/onlinepubs/9699919799/functions/strftime.html – Mat May 03 '13 at 11:37
  • Wouldn't it be simpler to use [`std::strftime`](http://en.cppreference.com/w/cpp/chrono/c/strftime)? – Some programmer dude May 03 '13 at 11:38
  • [Boost - Date Time](http://www.boost.org/doc/libs/1_53_0/doc/html/date_time/examples.html#date_time.examples.dates_as_strings) – M456 May 03 '13 at 11:40
  • Here is a [question](http://stackoverflow.com/questions/5018188/how-to-format-a-datetime-to-string-using-boost) (and answer) about how to do this using boost (if you somehow cannot use C++11): – maverik May 03 '13 at 11:46

7 Answers7

208

Since C++11 you could use std::put_time from iomanip header:

#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 is a stream manipulator, therefore it could be used together with std::ostringstream in order to convert the date to a string:

#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;
}
awesoon
  • 32,469
  • 11
  • 74
  • 99
  • 35
    `std::put_time` is still missing in gcc 4.9. – Yuriy Petrovskiy Aug 15 '14 at 21:30
  • 5
    gcc 5.0 has it, but not the earlier versions. – ABCD Jul 14 '15 at 02:15
  • @soon I have a question. In my code, I have a function that is supposed to return a time. What should be the return type of a function, that returns the current time? –  Sep 18 '16 at 15:57
  • @ArnavBorborah, it depends. You may return time in [Unix format](https://en.wikipedia.org/wiki/Unix_time), [Boost Local date time](http://www.boost.org/doc/libs/1_61_0/doc/html/date_time/local_time.html#date_time.local_time.local_date_time) or create your own type. – awesoon Sep 18 '16 at 16:06
  • localtime is not thread safe. Consider using localtime_r instead. – Homer6 Dec 26 '16 at 20:56
  • @Homer6 it's not standard. See also: [Will getting the current date/time be thread-safe in C++20?](https://stackoverflow.com/q/48106291/673852) – Ruslan Nov 20 '19 at 18:34
140

Non C++11 solution: With the <ctime> header, you could use strftime. Make sure your buffer is large enough, you wouldn't want to overrun it and wreak havoc later.

#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;
}
xuhdev
  • 8,018
  • 2
  • 41
  • 69
max
  • 4,248
  • 2
  • 25
  • 38
  • 3
    And what if it overflows the buffer ? I suppose there should be a return value to `strftime` that you need to inspect in real code no ? – Matthieu M. May 03 '13 at 12:17
  • 6
    It doesn't take much thinking for any given format string to compute a maximum possible string length. – Rafael Baptista May 03 '13 at 13:05
  • 1
    I don't understand why you can pass rawtime by value on the 10th line from the top, as time acceps a pointer to a time_t type : http://www.cplusplus.com/reference/ctime/time/ In the example on that page they used time() the same way which i don't understand. Can anyone explain me this? – Michahell Jan 28 '15 at 14:23
  • 1
    There's an `&` there. That means instead of the contents of the `rawtime` variable, it's address in memory will be passed... which is what is stored in a pointer variable. – max Jan 30 '15 at 04:57
  • To get milliseconds: auto now = std::chrono::system_clock::now(); std::chrono::time_point epoch; int ms = std::chrono::duration_cast(now - epoch).count() % 1000; – scrutari Apr 27 '16 at 10:56
  • Sadly this function returns 0 and doesn't format the date/time correctly on Windows 10. (At least for me). – SimonC May 29 '19 at 07:15
29

you can use asctime() function of time.h to get a string simply .

time_t _tm =time(NULL );

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

Sample output:

The current date/time is:Fri Oct 16 13:37:30 2015
ABCD
  • 7,914
  • 9
  • 54
  • 90
birubisht
  • 890
  • 8
  • 16
  • 3
    No, you can't: asctime does not deliver the date/time format requested in the question! – Aconcagua Feb 02 '15 at 15:44
  • 3
    @Aconcagua While it doesn't, it does give you time in a string. The code is clean and concise. – ABCD Oct 16 '15 at 02:36
  • 5
    Clean and concise code does not help if it does not provide what one wants or needs. Want a truck (string), you get one. Wanting to transport liquids, you need a tanker truck and won't be happy getting a dump truck... – Aconcagua Oct 16 '15 at 07:47
  • 4
    Nice answer, but asctime() has the VERY bad idea of returning a LF terminated String... – solendil Nov 09 '15 at 10:56
  • 1
    Furthermore `asctime` is not locale-sensitive like `strftime` is. – Roi Danton Aug 01 '17 at 08:51
17

With C++20, time point formatting (to string) is available in the (chrono) standard library. 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';
}

Output

13-12-2021 09:24:44

It works in Visual Studio 2019 (v16.11.5) with the latest C++ language version (/std:c++latest).

Synck
  • 2,727
  • 22
  • 20
  • Clarification: This gives the current UTC time, whereas the OP appears to want the current local time according to his computer's currently set time zone. This is also easy in C++20. – Howard Hinnant Jun 08 '22 at 17:49
7

Using C++ in MS Visual Studio 2015 (14), I use:

#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;
}
Black
  • 5,023
  • 6
  • 63
  • 92
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;
}
AGG GAA
  • 63
  • 1
  • 3
  • 3
    Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation](https://meta.stackexchange.com/q/114762/349538) would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you’ve made, like `#include`s. – Melebius Sep 13 '18 at 12:29
  • 3
    What does this actually return? – Steve Smith Sep 18 '18 at 10:53
  • @Steve Smith The output is: Tue Sep 14 14:17:16 2021 – phamuc Sep 14 '21 at 12:18
2

I wanted to use the C++11 answer, but I could not because GCC 4.9 does not support std::put_time.

std::put_time implementation status in GCC?

I ended up using some C++11 to slightly improve the non-C++11 answer. For those that can't use GCC 5, but would still like some C++11 in their date/time format:

 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());
Community
  • 1
  • 1
DiB
  • 554
  • 5
  • 19