Click here to Skip to main content
15,880,651 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I need a way to manage a date, including milliseconds: get current date and time, add given number of milliseconds to it. The first part is completed.
C++ version up to C++14.
Thanks.

Update: some background. I have a file with timestamp in the beginning, and number of records, each one contains number of milliseconds from this initial time:

2108 6 21 15 14 56 588
1000 message
5577 message
10000 message
...

So, I need to print every message with its full time. Since I already have time_point to timestamp conversion, I actually need an opposite conversion, which looks a bit tricky.

What I have tried:

C++
#include <chrono>
#include <ctime>

struct timestamp
{
    int year;    // 0-based 
    int month;   // [1-12]
    int day;     // [1-31]
    int hour;    // [0-23]
    int minute;  // [0-59]
    int sec;     // [0-59]
    int ms;      // [0-999]
};

// Done
timestamp get_local_date()
{
    timestamp t;

    auto now = std::chrono::system_clock::now();
    auto seconds = std::chrono::time_point_cast<std::chrono::seconds>(now);
    auto fraction = now - seconds;
    auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(fraction);

    time_t tnow = std::chrono::system_clock::to_time_t(now);
    tm* ptm = localtime(&tnow);

    t.year = ptm->tm_year + 1990;
    t.month = ptm->tm_mon + 1;
    t.day = ptm->tm_mday;
    t.hour = ptm->tm_hour;
    t.minute = ptm->tm_min;
    t.sec = ptm->tm_sec;
    t.ms = static_cast<int>(milliseconds.count());

    return t;
}

// ??
timestamp add(const timestamp& t, int ms)
{
    // compute new normalized timestamp by adding given ms count to t
}
Posted
Updated 21-Jun-18 2:20am
v7

To simplify calculations I would use a structure that does not contain the individual fields but a single or two values.

If you only want to support Windows you can use the FILETIME structure (Windows)[^].

Alternatively and for general OS support use the timeval structure (Windows)[^]. Here just add the members and when the addtion of the tv_usecs overflows (>= 1E6), increment tv_sec and subtract 1E6 from tv_usec.

For both structures there are conversion functions to other time formats so that you can get access to the individual date and time fields. The advantage of the timeval structure is that you have direct access to the fraction of second field when the converted format does not support such.

[EDIT]
If you still want to use your structure, write conversion functions to and from one of the above mentioned structures and use those to perform the caluclation.

Note also that your structure is very similar to the SYSTEMTIME structure (Windows)[^]. If you use that, there are existing conversion functions to and from FILETIME.
[/EDIT]

[EDIT2]
Untested examples from scratch:
C++
timeval add(const timeval& tv, int ms)
{
    timeval tv_res = { ms / 1000, 1000 * (ms % 1000)};
    tv_res.tv_sec += tv.tv_sec;
    tv_res.tv_usec += tv.tv_usec;
    if (tv_res.tv_usec >= 1000000)
    {
        tv_res.tv_sec++;
        tv_res.tv_usec -= 1000000;
    }
    return tv_res;
}

timestamp add(const timestamp& t, int ms)
{
    return TimeValToTimeStamp(add(TimeStampToTimeVal(t), ms));
}
All you need now are the conversion functions (TimeValToTimeStamp() left as an exercise):
C++
timeval TimeStampToTimeVal(const timestamp& t)
{
    struct tm tmt = { 0 };
    tmt.tm_year = t.year;
    tmt.tm_mon = t.month;
    tmt.tm_mday = t.day;
    tmt.tm_hour = t.hour;
    tmt.tm_min = t.minute;
    tmt.tm_sec = t.sec;
    timeval tv;
    tv.sec = (long)mktime(&tmt);
    tv.usec = t.ms * 1000;
    return tv;
}
[/EDIT2]
 
Share this answer
 
v3
Comments
11917640 Member 24-Jun-18 4:44am    
mktime was the function I was looking for. It allows to return from human-readable timestamp back to computer time. Thanks for this hint.
Than you need the High resolution time functions for Windows. Pay attention to the details as resolution and data type and its size.
 
Share this answer
 
I would
  • Throw away the get_local_date function.
  • Make a time_point_to_timestamp function.
  • Make a timestamp_to_timepoint function.
  • Implement add using the above functions and the time_point::operator+=.
 
Share this answer
 
Comments
11917640 Member 21-Jun-18 8:09am    
Exactly, timestamp_to_timepoint is my real problem.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900