getting chrono time in specific way
Asked Answered
G

2

0

I have following C code:

uint64_t combine(uint32_t const sec, uint32_t const usec){
    return (uint64_t) sec << 32 | usec;
};

uint64_t now3(){
    struct timeval tv;

    gettimeofday(&tv, NULL);

    return combine((uint32_t) tv.tv_sec, (uint32_t) tv.tv_usec);
}

What this do it combine 32 bit timestamp, and 32 bit "something", probably micro/nanoseconds into single 64 bit integer.

I have really hard time to rewrite it with C++11 chrono.

This is what I did so far, but I think this is wrong way to do it.

auto tse = std::chrono::system_clock::now().time_since_epoch();
auto dur = std::chrono::duration_cast<std::chrono::nanoseconds>( tse ).count();
uint64_t time = static_cast<uint64_t>( dur );

Important note - I only care about first 32 bit to be "valid" timestamp.

Second 32 bit "part" can be anything - nano or microseconds - everything is good as long as two sequential calls of this function give me different second "part".

Geomorphic answered 9/11, 2015 at 16:27 Comment(2)
What you've done is get a count of nanoseconds since 1970-01-01 UTC and stored it in a uint64_t. If that's what you wanted, you did it right. The duration_cast could be simplified to just nanoseconds{tse}, but that isn't going to change the result.Costard
i want seconds in one int, milliseconds in another. i think i found how to do it, but will update it tomorrowGeomorphic
C
1

i want seconds in one int, milliseconds in another.

Here is code to do that:

#include <chrono>
#include <iostream>

int
main()
{
    auto now = std::chrono::system_clock::now().time_since_epoch();
    std::cout << now.count() << '\n';
    auto s = std::chrono::duration_cast<std::chrono::seconds>(now);
    now -= s;
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now);
    int si = s.count();
    int msi = ms.count();
    std::cout << si << '\n';
    std::cout << msi << '\n';
}

This just output for me:

1447109182307707
1447109182
307
Costard answered 9/11, 2015 at 22:48 Comment(1)
works perfectly. i finally changed from milliseconds to microseconds, because seems gettimeofday give microseconds after all.Geomorphic
H
1

The C++11 chrono types use only one number to represent a time since a given Epoch, unlike the timeval (or timespec) structure which uses two numbers to precisely represent a time. So with C++11 chrono you don't need the combine() method.

The content of the timestamp returned by now() depends on the clock you use; there are tree clocks, described in http://en.cppreference.com/w/cpp/chrono :

system_clock             wall clock time from the system-wide realtime clock
steady_clock             monotonic clock that will never be adjusted
high_resolution_clock    the clock with the shortest tick period available

If you want successive timestamps to be always different, use the steady clock:

auto t1 = std::chrono::steady_clock::now();
...
auto t2 = std::chrono::steady_clock::now();
assert (t2 > t1);

Edit: answer to comment

#include <iostream>
#include <chrono>
#include <cstdint>

int main()
{
    typedef std::chrono::duration< uint32_t, std::ratio<1> > s32_t;
    typedef std::chrono::duration< uint32_t, std::milli > ms32_t;

    s32_t  first_part;
    ms32_t second_part;

    auto t1 = std::chrono::nanoseconds( 2500000000 ); // 2.5 secs

    first_part  = std::chrono::duration_cast<s32_t>(t1);
    second_part = std::chrono::duration_cast<ms32_t>(t1-first_part);

    std::cout << "first part   = " << first_part.count() << " s\n"
              << "seconds part = " << second_part.count() << " ms" << std::endl;

    auto t2 = std::chrono::nanoseconds( 2800000000 ); // 2.8 secs

    first_part  = std::chrono::duration_cast<s32_t>(t2);
    second_part = std::chrono::duration_cast<ms32_t>(t2-first_part);

    std::cout << "first part   = " << first_part.count() << " s\n"
              << "seconds part = " << second_part.count() << " ms" << std::endl;
}

Output:

first part   = 2 s
seconds part = 500 ms
first part   = 2 s
seconds part = 800 ms
Haplography answered 9/11, 2015 at 16:49 Comment(1)
This is used for something like memcached cache expiration, but I need it in format similar to the one from C gettimeofday. e.g. first part 32 bit timestamp, second part - whatever, as long as it is changed more frequently than 1 sec. I can get 32 bit timestamp, but I have no idea how to collect "second" part using chrono.Geomorphic
C
1

i want seconds in one int, milliseconds in another.

Here is code to do that:

#include <chrono>
#include <iostream>

int
main()
{
    auto now = std::chrono::system_clock::now().time_since_epoch();
    std::cout << now.count() << '\n';
    auto s = std::chrono::duration_cast<std::chrono::seconds>(now);
    now -= s;
    auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now);
    int si = s.count();
    int msi = ms.count();
    std::cout << si << '\n';
    std::cout << msi << '\n';
}

This just output for me:

1447109182307707
1447109182
307
Costard answered 9/11, 2015 at 22:48 Comment(1)
works perfectly. i finally changed from milliseconds to microseconds, because seems gettimeofday give microseconds after all.Geomorphic

© 2022 - 2024 — McMap. All rights reserved.