[Boost-users] convert separate year, month, day, hour, minute, secs, ms to milliseconds since epoch

53 views
Skip to first unread message

Victor Yankee via Boost-users

unread,
Mar 4, 2019, 3:54:53 AM3/4/19
to boost...@lists.boost.org, Victor Yankee
I am using C++14 and boost 1.64.0 (could move to newest boost), and need to convert date and time pieces to a single value for milliseconds since the epoch. This is what I have:

int64_t msSinceEpoch(int year,int month,int day,int hour,int minute,int second,int ms)
            {
            struct std::tm t;
            t.tm_sec    = second;
            t.tm_min    = minute;
            t.tm_hour   = hour;
            t.tm_mday   = day;
            t.tm_mon    = month-1;
            t.tm_year   = year-1900;
            t.tm_isdst  = 0;
            return (1000* timegm(&t))+ms; // is timegm cross-platform?
            }

Is there a better way? Could not figure out how to use boost::chrono :( Something else?

Kind Regards,
Vic

Gavin Lambert via Boost-users

unread,
Mar 4, 2019, 5:18:12 PM3/4/19
to boost...@lists.boost.org, Gavin Lambert
On 4/03/2019 09:45, Victor Yankee wrote:
> I am using C++14 and boost 1.64.0 (could move to newest boost), and need
> to convert date and time pieces to a single value for milliseconds since
> the epoch. This is what I have:
>
> int64_t msSinceEpoch(int year,int month,int day,int hour,int minute,int
> second,int ms)
>             {
>             struct std::tm t;
>             t.tm_sec    = second;
>             t.tm_min    = minute;
>             t.tm_hour   = hour;
>             t.tm_mday   = day;
>             t.tm_mon    = month-1;
>             t.tm_year   = year-1900;
>             t.tm_isdst  = 0;
>             return (1000* timegm(&t))+ms; // is timegm cross-platform?
>             }

timegm is not cross platform. mktime is, but uses local time instead of
UTC.

> Is there a better way? Could not figure out how to use boost::chrono :(
> Something else?

Boost.Chrono is for time intervals, not dates.

Boost.DateTime, however, has the ptime class which will solve this for you.
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
https://lists.boost.org/mailman/listinfo.cgi/boost-users

Leon Mlakar via Boost-users

unread,
Mar 4, 2019, 6:40:43 PM3/4/19
to Gavin Lambert via Boost-users, Leon Mlakar
On 04.03.2019 23:17, Gavin Lambert via Boost-users wrote:
> On 4/03/2019 09:45, Victor Yankee wrote:
>> I am using C++14 and boost 1.64.0 (could move to newest boost), and
>> need to convert date and time pieces to a single value for
>> milliseconds since the epoch. This is what I have:
>>
>> int64_t msSinceEpoch(int year,int month,int day,int hour,int
>> minute,int second,int ms)
>>              {
>>              struct std::tm t;
>>              t.tm_sec    = second;
>>              t.tm_min    = minute;
>>              t.tm_hour   = hour;
>>              t.tm_mday   = day;
>>              t.tm_mon    = month-1;
>>              t.tm_year   = year-1900;
>>              t.tm_isdst  = 0;
>>              return (1000* timegm(&t))+ms; // is timegm cross-platform?
>>              }
>
> timegm is not cross platform.  mktime is, but uses local time instead
> of UTC.
>
>> Is there a better way? Could not figure out how to use boost::chrono
>> :( Something else?
>
> Boost.Chrono is for time intervals, not dates.
>
> Boost.DateTime, however, has the ptime class which will solve this for
> you.

I think with C++11 something like:

std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()

might also do the trick.

Cheers,

Leon

Leon Mlakar via Boost-users

unread,
Mar 4, 2019, 6:51:54 PM3/4/19
to Gavin Lambert via Boost-users, Leon Mlakar

Err, then again, it might not until C++20. C++11 embarrassingly failed
to state what the Epoch is. So for now clocks are free to use their own
and currently the above is useless for cross-platform applications (but
so is timegm). I wonder how this works on Windows with VS2019?

degski via Boost-users

unread,
Mar 5, 2019, 1:12:11 AM3/5/19
to boost...@lists.boost.org, degski
On Tue, 5 Mar 2019 at 01:51, Leon Mlakar via Boost-users <boost...@lists.boost.org> wrote:
I wonder how this works on Windows with VS2019?

It returns 1551766256847 (so the same as https://www.epochconverter.com/, i.e. "Unix Time"), there's no reason to assume it returns something else with VS2019 (AFAICS), until/unless it supports C++20 and the std explicitly changes the behavior  (forces MS to break backward compatibility), you can be assured that it will be doing that for a while (until the Y38 problem raises its head).

degski
--
"Big boys don't cry" - Eric Stewart, Graham Gouldman

Leon Mlakar via Boost-users

unread,
Mar 5, 2019, 3:39:11 AM3/5/19
to degski via Boost-users, Leon Mlakar
On 05.03.2019 07:11, degski via Boost-users wrote:
On Tue, 5 Mar 2019 at 01:51, Leon Mlakar via Boost-users <boost...@lists.boost.org> wrote:
I wonder how this works on Windows with VS2019?

It returns 1551766256847 (so the same as https://www.epochconverter.com/, i.e. "Unix Time"), there's no reason to assume it returns something else with VS2019 (AFAICS), until/unless it supports C++20 and the std explicitly changes the behavior  (forces MS to break backward compatibility), you can be assured that it will be doing that for a while (until the Y38 problem raises its head).

Thank you for the information.

Behid the question was my, obviously incorrect, assumption that older visual studio versions, from times when c++20 was not yet conceived and epoch thus not set to Jan 1 AD 1970, are using some different epoch - as Microsoft frequently did, like Jan 1 AD 1 (.NET),  Jan 1 AD 1601 (NTFS), Jan 1 AD 1980 (DOS, FAT family of file systems). So seeing Microsoft embracing a standard thing like posix epoch without screaming and kicking is a nice surprise.

And it was late.

Cheers,

Leon

P.S. As for the Y38, std::chrono should be okay as it's not bound to 32-bit integrals.

degski via Boost-users

unread,
Mar 5, 2019, 4:06:56 AM3/5/19
to boost...@lists.boost.org, degski
On Tue, 5 Mar 2019 at 10:39, Leon Mlakar via Boost-users <boost...@lists.boost.org> wrote:

Behid the question was my, obviously incorrect, assumption that olde visual studio versions, from times when c++20 was not yet conceived and epoch thus not set to Jan 1 AD 1970, are using some different epoch - as Microsoft frequently did, like Jan 1 AD 1 (.NET),  Jan 1 AD 1601 (NTFS),

MS just implements the standard [in this case] and for timings within Windows (i..e. Windows.h), they have the FILETIME API, " Jan 1 AD 1 (.NET),  Jan 1 AD 1601 (NTFS)", etc (possibly because they realized the world was not created in 1970, but heck who knows).

Jan 1 AD 1980 (DOS, FAT family of file systems). So seeing Microsoft embracing a standard thing like posix epoch without screaming and kicking is a nice surprise.

Well at the time of DOS, there was no std, so one could forgive them (on this occasion) to not implement it correctly.

Sergey Spiridonov via Boost-users

unread,
Mar 11, 2019, 10:45:11 AM3/11/19
to boost...@lists.boost.org, Sergey Spiridonov, Victor Yankee
On Sun, 3 Mar 2019 12:45:17 -0800
Victor Yankee via Boost-users <boost...@lists.boost.org> wrote:

> I am using C++14 and boost 1.64.0 (could move to newest boost), and
> need to convert date and time pieces to a single value for
> milliseconds since the epoch. This is what I have:
>
> int64_t msSinceEpoch(int year,int month,int day,int hour,int
> minute,int second,int ms)
> {
> struct std::tm t;
> t.tm_sec = second;
> t.tm_min = minute;
> t.tm_hour = hour;
> t.tm_mday = day;
> t.tm_mon = month-1;
> t.tm_year = year-1900;
> t.tm_isdst = 0;
> return (1000* timegm(&t))+ms; // is timegm cross-platform?
> }
>
> Is there a better way?


time_tsec_since_epoch(int year, int month, int day,
int hour, int minute, int second)
{
static const boost::posix_time::ptime
epoch(boost::gregorian::date(1970,1,1));

boost::posix_time::ptime pt(
boost::gregorian::date(year, month, day),
boost::posix_time::time_duration(hour, minute, second)
);

boost::posix_time::time_duration since_epoch = pt - epoch;
return since_epoch.total_seconds();
}



--
Best regards, Sergey Spiridonov

Sergey Spiridonov via Boost-users

unread,
Mar 11, 2019, 10:51:06 AM3/11/19
to boost...@lists.boost.org, Sergey Spiridonov
On Sun, 3 Mar 2019 12:45:17 -0800
Victor Yankee via Boost-users <boost...@lists.boost.org> wrote:

> I am using C++14 and boost 1.64.0 (could move to newest boost), and
> need to convert date and time pieces to a single value for
> milliseconds since the epoch. This is what I have:
>
> int64_t msSinceEpoch(int year,int month,int day,int hour,int
> minute,int second,int ms)
> {
> struct std::tm t;
> t.tm_sec = second;
> t.tm_min = minute;
> t.tm_hour = hour;
> t.tm_mday = day;
> t.tm_mon = month-1;
> t.tm_year = year-1900;
> t.tm_isdst = 0;
> return (1000* timegm(&t))+ms; // is timegm cross-platform?
> }
>
> Is there a better way?

Sorry, previous was for seconds

#include <boost/date_time/posix_time/posix_time.hpp>

int64_t time_msec_since_epoch(int year, int month, int day,
int hour, int minute, int second, int msec)
{
static const boost::posix_time::ptime
epoch(boost::gregorian::date(1970,1,1));

boost::posix_time::ptime pt(
boost::gregorian::date(year, month, day),
boost::posix_time::time_duration(hour, minute, second) +
boost::posix_time::milliseconds(msec)
);

boost::posix_time::time_duration since_epoch = pt - epoch;
return since_epoch.total_milliseconds();
Reply all
Reply to author
Forward
0 new messages