Yves
Yves

Reputation: 12371

Why does the function about getting current time return a wrong time point

I'm working with C++11 and I wrote a function to get the current time point:

template <typename T = std::chrono::milliseconds>
using Clock = std::chrono::time_point<std::chrono::system_clock, T>;

// get current time point
template <typename T = std::chrono::milliseconds>
inline Clock<T> getCurrentTimePoint(int8_t timeZone = 0) {
    return std::chrono::time_point_cast<T>(std::chrono::system_clock::now()) +
        std::chrono::hours {timezone};
}

However, I just tested the function and it gave me a very strange output.

auto now1 = std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now());
auto now2 = getCurrentTimePoint<std::chrono::seconds>();
LOG(INFO) << "debug - now1:" << now1.time_since_epoch().count() << " now2:" << now2.time_since_epoch().count();

LOG(INFO) can print stream into a log file. So in the log file, I got this:

debug - now1:1641294039 now2:1537614039

So, now1 works as exptected but now2 is really weird because its value is a time point of about three years ago, which is 22/09/2018.

However, I've tried to make a demo here: https://godbolt.org/z/ns3116e63 and it always gives me a correct result.

I'm really confused.

My machine is Ubuntu 16.04.4 LTS. I'm using CMake to compile my project. I added add_definitions(-std=c++14) in the file CMakeLists.txt.

Update

I tested again the next day and here is the result.

I added two more functions, which are exactly the same except their names:

std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds> getCurrentTimePoint1(int8_t timeZone = 0) {
    return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()) + std::chrono::hours {timeZone};
}

std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds> getCurrentTimePoint2(int8_t timeZone = 0) { // OK
    return std::chrono::time_point_cast<std::chrono::seconds>(std::chrono::system_clock::now()) + std::chrono::hours {timeZone};
}

getCurrentTimePoint1 gave me the wrong result, just like now2 above. But getCurrentTimePoint2 gave me the correct result, just like now1 above. This is really weird...

Then I added more functions, such as the function without parameter to do more tests. At some moment, getCurrentTimePoint1 could generate a correct result too!

It seems that adding more functions returning std::chrono::time_point or calling these functions more times could solve this issue!

Upvotes: 0

Views: 900

Answers (1)

Yves
Yves

Reputation: 12371

Well, this is a very stupid mistake.

template <typename T = std::chrono::milliseconds>
inline Clock<T> getCurrentTimePoint(int8_t timeZone = 0) {
    return std::chrono::time_point_cast<T>(std::chrono::system_clock::now()) +
        std::chrono::hours {timezone}; // typo error! timeZone, instead of timezone
}

The variable timezone has been defined (man7.org/linux/man-pages/man3/tzset.3.html) and been included by chrono. That's why the compiler didn't generate any error.

Upvotes: 2

Related Questions