Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert unix timestamp to human readable date

Tags:

c++

time

Is there a contemporary way to convert unix timestamps to a human readable date? Since I want to circumnavigate the year 2038 problem, I want to use int64s. I target to convert e. g. 1205812558 to

year = 2008, month = 3, day = 18, hour = 17, minute = 18, second = 36

All I have is now

auto year = totalSeconds / secondsPerYear + 1970;
// month and day missing
auto hours = totalSeconds / 3600 % 24;
auto minutes = totalSeconds / 60 % 60;
auto seconds = totalSeconds % 60; 

2 Answers

In C++20 (according to the draft-spec for C++20 as it stands today), you will be able to say:

#include <chrono>
#include <iostream>

int
main()
{
    using namespace std;
    using namespace std::chrono;
    cout << sys_seconds{1205812558s} << '\n';
    cout << sys_seconds{32879409516s} << '\n';
}

and it will output:

2008-03-18 03:55:58
3011-11-28 17:18:36

These are datetimes in UTC.

You can use Howard Hinnant's date library to experiment with this extended <chrono> functionality today by adding:

#include "date/date.h"

and

    using namespace date;

to the above program. You can experiment online with this program here.


A comment below asks for what this looks like if the value is stored in uint64_t. The answer is that you need to convert the integral type to seconds, and then the seconds to sys_seconds:

uint64_t i = 1205812558;
cout << sys_seconds{seconds(i)} << '\n';

There do exist limits on this contemporary functionality, but they live out near the years +/-32K (far beyond the limits of the accuracy of the current civil calendar).

To be completely transparent, there do exist ways of doing this using only C++98/11/14/17, but they are more complicated than this, and are subject to multithreading bugs. This is due to the use of an antiquated C API that was designed before things like multithreading and C++ were on the horizon, and when the year 2001 was only associated with science fiction (e.g. gmtime).

like image 189
Howard Hinnant Avatar answered Oct 16 '25 20:10

Howard Hinnant


Wrapper

#include <chrono>
char* get_time(time_t unix_timestamp)
{
char time_buf[80];
struct tm ts;
ts = *localtime(&unix_timestamp);
strftime(time_buf, sizeof(time_buf), "%a %Y-%m-%d %H:%M:%S %Z", &ts);

return time_buf;
}
like image 40
Caspar Quast Avatar answered Oct 16 '25 21:10

Caspar Quast



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!