Home > Net >  How can I round Time epoch to previous midnight
How can I round Time epoch to previous midnight

Time:06-14

Let's say I have : time in msec = 1655205146419 , which is generated using :

auto msec = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();

Tuesday, June 14, 2022 11:12:26.419 AM

And I want to round it up to the previous midnight :

Tuesday, June 14, 2022 00:00:00.00 AM

any ideas how ?

CodePudding user response:

You can use https://en.cppreference.com/w/cpp/chrono/time_point/floor with a duration https://en.cppreference.com/w/cpp/chrono/duration of 1 day:

#include <iostream>
#include <chrono>
 
int main()
{
    using Day = std::chrono::days;
    using std::chrono::duration_cast;
    auto start = std::chrono::system_clock::now();
    std::cout << duration_cast<std::chrono::milliseconds>(std::chrono::floor<Day>(start).time_since_epoch()).count() << "\n";
}

https://godbolt.org/z/z89nr4Mo3

increased readability when storing the days in a variable:

auto start = std::chrono::system_clock::now();
auto days = std::chrono::floor<Day>(start).time_since_epoch();
std::cout << duration_cast<std::chrono::milliseconds>(days) << std::endl;

CodePudding user response:

You could do it this way, not as pretty, but you can play a bit with std::tm and get answers that you wish.

#include <ctime>
#include <iostream>
#include <string>

int main() {
    std::time_t now = time(0);
    std::tm tstruct;

    char current_time[20];
    char last_midnight[20];
    tstruct = *std::localtime(&now);
    std::strftime(current_time, sizeof(current_time), "%Y-%m-%d %X", &tstruct);
    tstruct.tm_hour = 00;
    tstruct.tm_min = 00;
    tstruct.tm_sec = 00;
    std::strftime(last_midnight, sizeof(last_midnight), "%Y-%m-%d %X", &tstruct);
    std::cout << "current_time: " << current_time << std::endl;
    std::cout << "last_midnight: " << last_midnight << std::endl;
    return 0;
}

Output results

CodePudding user response:

Let's say I have : time in msec = 1655205146419

I'd try to stay within the chrono domain as much as it is possible, but if you are forced to use milliseconds since the epoch as an input value:

auto midnight_tp = system_clock::time_point(milliseconds(msec)) - 
              milliseconds(msec) % days(1);
// or
auto midnight_tp = floor<days>(system_clock::time_point(milliseconds(msec)));

Getting to the unitless milliseconds since epoch again will just repeat what you've already done earlier:

auto midnight_msec =
    duration_cast<milliseconds>(midnight_tp.time_since_epoch()).count();

Demo

  • Related