0

I have created std::chrono::milliseconds ms and std::chrono::nanoseconds ns from std::chrono::system_clock::now().time_since_epoch(). From that duration I created timepoints and convert it to time_t using system_clock::to_time_t and print it using ctime function. But the time printed is not same. As I understand the time_point have duration and duration have rep and period (ratio). So time_point must have same value up to millisecond precision in both time_points. Why the output is different?

Here is my code

#include <ctime> #include <ratio> #include <chrono> #include <iostream> using namespace std::chrono; int main () { std::chrono::milliseconds ms = std::chrono::duration_cast < std::chrono::milliseconds > (std::chrono::system_clock::now().time_since_epoch()); std::chrono::nanoseconds ns = std::chrono::duration_cast< std::chrono::nanoseconds > (std::chrono::system_clock::now().time_since_epoch()); std::chrono::duration<unsigned int,std::ratio<1,1000>> today_day (ms.count()); std::chrono::duration<system_clock::duration::rep,system_clock::duration::period> same_day(ns.count()); system_clock::time_point abc(today_day); system_clock::time_point abc1(same_day); std::time_t tt; tt = system_clock::to_time_t ( abc ); std::cout << "today is: " << ctime(&tt); tt = system_clock::to_time_t ( abc1 ); std::cout << "today is: " << ctime(&tt); return 0; } 

3 Answers 3

3

This line:

std::chrono::duration<unsigned int,std::ratio<1,1000>> today_day (ms.count()); 

is overflowing. The number of milliseconds since 1970 is on the order of 1.5 trillion. But unsigned int (on your platform) overflows at about 4 billion.

Also, depending on your platform, this line:

std::chrono::duration<system_clock::duration::rep,system_clock::duration::period> same_day(ns.count()); 

may introduce a conversion error. If you are using gcc, system_clock::duration is nanoseconds, and there will be no error.

However, if you're using llvm's libc++, system_clock::duration is microseconds and you will be silently multiplying your duration by 1000.

And if you are using Visual Studio, system_clock::duration is 100 nanoseconds and you will be silently multiplying your duration by 100.

Here is a video tutorial for <chrono> which may help, and contains warnings about the use of .count() and .time_since_epoch().

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the tutorial.
Sir i hava a question is the time_since_epoch is the duration between reference point(1970-01-01T00:00:00Z) and current UTC time or it is the duration between reference point(1970-01-01T00:00:00Z) and current local time.I guess it is the first one.
Officially the system_clock::time_since_epoch() is unspecified. However all implementations are measuring the current UTC time since 1970-01-01T00:00:00Z, excluding leap seconds. That is, in this measure, every day is exactly 86400 seconds. This is known as Unix Time. The current C++20 draft specification makes this definition official.
Why hasn't this tutorial be linked in all the other chrono Q&A threads? Thanks a lot! And now I know, why I see your name on all the (helpful) answers I've been studying today... Wish I could +1 it more than once.
Thanks for the feedback.
0

The conversions you do manually do not look right.

You should use duration_cast for conversions because they are type-safe:

auto today_day = duration_cast<duration<unsigned, std::ratio<86400>>>(ms); auto same_day = duration_cast<system_clock::duration>(ns); 

Outputs:

today is: Thu Jul 26 01:00:00 2018 today is: Thu Jul 26 13:01:08 2018 

Comments

0

Because you throw away the duration info, and then interpret an integer value as a different duration type

std::chrono::duration<unsigned int,std::ratio<1,1000>> today_day (ms.count()); 

milliseconds -> dimensionless -> 1 / 1000 seconds (i.e. milliseconds)

std::chrono::duration<system_clock::duration::rep,system_clock::duration::period> same_day(ns.count()); 

nanoseconds -> dimensionless -> system clocks

You should instead just duration_cast again

#include <ctime> #include <ratio> #include <chrono> #include <iostream> using namespace std::chrono; int main () { milliseconds ms = duration_cast<milliseconds>(system_clock::now().time_since_epoch()); nanoseconds ns = duration_cast<nanoseconds>(system_clock::now().time_since_epoch()); system_clock::time_point abc(duration_cast<system_clock::duration>(ms)); system_clock::time_point abc1(duration_cast<system_clock::duration>(ns)); std::time_t tt; tt = system_clock::to_time_t ( abc ); std::cout << "today is: " << ctime(&tt); tt = system_clock::to_time_t ( abc1 ); std::cout << "today is: " << ctime(&tt); return 0; } 

3 Comments

Thanks for your response.I think for my code it will be better it will fail at compile time if i did not pass system_clock::duration to system_clock::time_point at constructor.
@user1438832 why? you can just as easily duration_cast
Yes i got it. But i think it will be better if the code i posted failed at compile time if as i did not pass system_clock::duration to system_clock::time_point at constructor. It can check the rep and period of passed duration is matched with system_clock::duration::rep and system_clock::duration::period if not failed at compile time.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.