Search code examples
c++c++-chrono

how many days left between 2 dates using std::chrono


I'm trying to check how many days are left for my application, one from the current time and the second one from a std::string that comes from a database, but every time I try to subtract the 2 dates using

std::chrono::duration<int>

I get "expected unqualified-d before = token", not sure what is chrono expecting below its my code

void Silo::RevisarDiasRestantes(){     // Check how many days are left, if the serial is 00 is for life

// obtain the current time with std::chrono and convert to struct tm * so it can be convert to an std::string
std::time_t now_c;
std::chrono::time_point<std::chrono::system_clock> now;
typedef std::chrono::duration<int> tiempo;
struct tm * timeinfo;
char buffer[80]; 

now = std::chrono::system_clock::now();
now_c = std::chrono::system_clock::to_time_t(now);
time (&now_c);
timeinfo = localtime(&now_c);
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeinfo);
std::string str(buffer);

Log("Tiempo usando Chrono " + QString::fromStdString(str));

for (int a{0} ; a<1000 ; )   // just an standard for
{
    a++;
}

//   convert std::string to std::time_t and then convert to a std::chrono
std::string i = str;
std::chrono::time_point<std::chrono::system_clock> end;
struct std::tm tm;
std::istringstream iss;
iss.str(i);
iss >> std::get_time(&tm,"%Y:%m:%d %H:%M:%S");

std::time_t time = mktime(&tm);
end = std::chrono::system_clock::from_time_t(time);
tiempo = end - now;                          <-------------------- heres the problem
Log( "Diferencia de tiempo: " + QString::number(tiempo.count()));

}

Edit: one thing I didn't notice until today if I try using istringstream to std::get_time the program compiles but it fails at runtime, asking for a "missing basic_istringstream" in the dynamic library, so I can't use that; is there another alternative to give the string to get_time?

Edit2: I didn't notice until JhonFilleau pointed the problem, no more working at late hours, thannks


Solution

  • There's two problems, one of which is pointed out by JohnFilleau in the comments.

    1. You are assigning to a type instead of to a variable. It is as if you are coding:

     

    int = 3;
    

    instead of:

    int i = 3;
    

    You need something like:

    tiempo t = end - now; 
    
    1. You are trying to implicitly convert from the precision of system_clock::time_point (typically microseconds to nanoseconds), to a precision of seconds. And chrono won't let you do that conversion implicitly because it loses precision.

    But you can force it with duration_cast:

    tiempo t = std::chrono::duration_cast<std::chrono::seconds>(end - now);
    

    Finally, there's no need for

    typedef std::chrono::duration<int> tiempo;
    

    This is just another name for seconds, but stored in an int instead of something less prone to overflow. auto can be more easily used here:

    auto t = std::chrono::duration_cast<std::chrono::seconds>(end - now);
    

    and the type of t is std::chrono::duration<I> where I is a signed integral type of at least 35 bits (typically 64 bits). And there is a convenience type alias for this type named std::chrono::seconds.

    If you really want this type named tiempo then I recommend:

    using tiempo = std::chrono::seconds;
    // ...
    auto t = std::chrono::duration_cast<tiempo>(end - now);
    

    or:

    tiempo t = std::chrono::duration_cast<tiempo>(end - now);