-1

I am trying to see whether my data is 120 second old or not by looking at the timestamp of the data so I have below small code in my library project which is using std::chrono package:

uint64_t now = duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
bool is_old = (120 * 1000 < (now - data_holder->getTimestamp()));

// some logging to print out above values
LOG4CXX_WARN(logger, "data logging, now: " << now << ", data holder timestamp: " << data_holder->getTimestamp() << ", is_old: " << is_old << ", difference: " << (now -         data_holder->getTimestamp()));

In the above code data_holder->getTimestamp() is uint64_t which returns timestamp in milliseconds.

Now when I print out now variable value, I am seeing this 433425679 and when I print out data_holder->getTimestamp() value which is 1437943796841 and the difference of now and data holder timestamp is coming as 18446742636199180454 as shown below in the logs:

2015-07-26 13:49:56,850 WARN 0x7fd050bc9700 simple_process - data logging, now: 433425679 , data holder timestamp: 1437943796841 , is_old: 1 , difference: 18446742636199180454

Now if I convert data holder timestamp 1437943796841 using epoch converter, I see this:

Your time zone: 7/26/2015, 1:49:56 PM

which is exactly same as the timestamp shown in the logs 2015-07-26 13:49:56,850 WARN so that means my data doesn't look to be 120 second old data. If yes, then why I am seeing is_old value as 1?

Now if I run this simple main program, I see is_old is returning 0 instead of 1:

#include <iostream>

int main ()
{

bool is_old = (120 * 1000 < (433425679 - 1437943796841));
std::cout<<"is_old: " << is_old << std::endl;
}

What is going on? Why it is returning 0 when I run from main method as compared to 1 when I log it from my project. Does that mean the way I am running my main code is different as compared to way my library was build using cmake command? I am building my project executable using cmake command which is generating a tar file and then I am running it by untarring the tar file. I am running on Ubuntu 14.04 box.

Earlier, I was thinking I need to use system_clock instead of steady_clock but after I run it from main method, it looks like something else is going on.

user1950349
  • 4,738
  • 19
  • 67
  • 119

1 Answers1

1

Unsigned integer arithmetic is defined as arithmetic modulo 2^numBits.

That means when you do now - data_holder->getTimestamp() with your unsigned variables and getTimestamp() is greater than now as in your example, the operation will wrap and you will not get a negative value, but a (usually pretty big) one of the same unsigned integer type as the inputs.

If you use literals instead, their types will be signed and thus the result will be negative, as expected.

Now whether subtracting some timestamp from whatever source and the value returned by steady_clock::now makes sense in the first place is a different question. It most likely does not. You should compare the current time with some creation time you got from the same source (e.g. both from std::steady_clock) instead.

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
  • Thanks for the help. I was not able to understand so you are saying there is some issue in the code which is causing this? – user1950349 Jul 26 '15 at 21:56
  • @user1950349 What exactly do you not understand? The unsigned integer arithmetic part? If so, does [this](http://stackoverflow.com/questions/16056758/c-c-unsigned-integer-overflow) help? – Baum mit Augen Jul 26 '15 at 21:58
  • No I mean is there any issue in the code which is causing this problem or the code looks right? Also, why main method works but not when I log it from my library project. – user1950349 Jul 26 '15 at 22:01
  • @user1950349 I don't understand your comments. I explained why you get different results and that your current approach is most likely wrong, and I offered a working alternative. If you need clarification or more information to any of them, please be more specific. – Baum mit Augen Jul 26 '15 at 22:03
  • Ok got it now after I read it again. Now problem is from Java component, I am sending this `data_holder->getTimestamp()` using `System.currentTimeMillis()` which my C++ component is getting it and then I am retrieving it from `data_holder->getTimestamp()` so I am not sure how we can use match the epoch of both the clock then. – user1950349 Jul 26 '15 at 22:06
  • @user1950349 Short answer: You can't. The C++ clocks need not have the same epoch as your timestamp, so the values may be (and in your case seem to be) totally unrelated to another. Compare two time values you got from the same clock device instead. – Baum mit Augen Jul 26 '15 at 22:09
  • 1
    @BaummitAugen or, figure out when the other clock's epoch is, and do a subtraction of now from that time, then convert that delta-time to seconds (or milliseconds or minutes or whatever). – Yakk - Adam Nevraumont Jul 26 '15 at 22:26
  • I guess I am wrong, that timestamp is not from the Java side, it is time from C++ code only using steady_clock. – user1950349 Jul 26 '15 at 22:27