4

I would like to get current time in milliseconds since a specific epoch e.g. Jan 1, 2016.

The reason to do this is to avoid using 8 bytes for std::chrono::milliseconds.
I would like to store the result in a 4byte data type instead.

std::chrono::steady_clock() uses default epoch which is unspecified.

Aman Jain
  • 10,927
  • 15
  • 50
  • 63
  • Related: http://stackoverflow.com/questions/33964461/handling-julian-dates-in-c11-14 –  Jan 12 '16 at 20:06
  • 2
    I would suggest you go and make your own clock class for this purpose which returns from `now` a `time_point>` – David Jan 12 '16 at 20:53

1 Answers1

3

Here is how you can create your own clock as suggested in the comments by David.

#include "date.h"
#include <cstdint>
#include <iostream>

struct myclock
{
    using rep        = std::int32_t;
    using period     = std::milli;
    using duration   = std::chrono::duration<rep, period>;
    using time_point = std::chrono::time_point<myclock>;
    static constexpr bool is_steady = false;

    static time_point now() noexcept
    {
        using namespace std::chrono;
        using namespace date;
        return time_point{duration_cast<duration>(system_clock::now()
                                                - sys_days{jan/1/2016})};
    }
};

static_assert(sizeof(myclock::time_point) == 4, "");
static_assert(sizeof(myclock::duration) == 4, "");

int
main()
{
    auto tp = myclock::now();
    std::cout << tp.time_since_epoch().count() << '\n';
}

The representation is specified to be int32_t as you specified, and the precision is milliseconds, as you specified.

To get the epoch you specified I got an assist from this date library which makes it very easy to interoperate dates and system_clock::time_point. I simply subtract off your desired epoch from system_clock::now(), and cast that duration to myclock::duration (32 bit milliseconds).

Running this program just now output for me:

1207186990

which is 13.97 days.

You can compute the range of your clock with this code:

using namespace date;
using namespace std::chrono;
auto min = milliseconds{myclock::duration::min()} + sys_days{jan/1/2016};
auto max = milliseconds{myclock::duration::max()} + sys_days{jan/1/2016};
std::cout << min << '\n';
std::cout << max << '\n';

The explicit conversion to std::chrono::milliseconds is necessary to avoid overflow. This will output:

2015-12-07 03:28:36.352
2016-01-25 20:31:23.647

So better hurry. myclock will overflow in another 10 days. :-)

Community
  • 1
  • 1
Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577