Проверка, находится ли time_t между другими time_t с некоторой погрешностью

У меня есть две переменные time_t: timeA и timeB.

То, что я хочу сделать, это проверить, совпадает ли время A с временем B. Тем не менее, я знаю, что в некоторых случаях они не будут точно такими же, и между ними может быть разница в 1 или 2 секунды, поэтому я действительно хочу проверить это:

    if (timeB - 2sec) <= timeA <= (timeB + 2sec)

Возможно ли это сделать?

Я полагаю, что один из вариантов - не использовать time_t, а вместо этого оставить timeB в качестве структуры tm, и непосредственно перед сравнением вычтите две секунды и создайте time_t timeBminus, а затем добавьте четыре секунды и создайте time_t timeBplus. Проблема в том, что я буду сравнивать несколько миллионов пар timeA - timeB и хочу, чтобы все было как можно проще и быстрее.

Как мне это сделать?

4 ответа

Решение

Что-то вроде -

if (std::fabs(std::difftime(timeA, timeB)) < 2.0) 

(Не могу проверить точный тип и т.д. отсюда, но я думаю, что идея верна)

Даже если time_t обычно представляет секунды, это на самом деле не стандартное поведение. Детали time_t оставлены для реализации (в соответствии с этим)

Вместо использования time_t напрямую, лучше всего использовать struct timespec и использовать tv_sec член. Чтобы проверить, находятся ли они на расстоянии 2 с друг от друга:

static inline bool close_enough(struct timespec &ts1, struct timespec &ts2)
{
    const int64_t sec_in_nsec = 1000000000ll;
    int64_t ts1_nsec = ts1.tv_sec * sec_in_nsec + ts1.tv_nsec;
    int64_t ts2_nsec = ts2.tv_sec * sec_in_nsec + ts2.tv_nsec;

    return ts1_nsec >= ts2_nsec - 2 * sec_in_nsec && ts1_nsec <= ts2_nsec + 2 * sec_in_nsec;
}

или используйте то же выражение в if, Вызов функции будет оптимизирован, так что не беспокойтесь об этом. С помощью abs как предложено в других ответах, это хорошо, даже если он преобразует ваши целые числа в числа с плавающей запятой и выполняет операции с плавающей запятой.

Обновить

С помощью time_t, ты можешь использовать difftime чтобы получить разницу между двумя разами. Снова:

static inline bool close_enough(time_t &t1, time_t &t2)
{
    double d = difftime(t1, t2);
    return d >= -2 && d <= 2;
}
if(abs(timeA - timeB) <= 2) {
  // yay!
}

Если ваш компилятор поддерживает C++11, вы должны использовать chrono вместо ctime:

#include <iostream>
#include <chrono>
#include <tuple>

int main() {
    std::chrono::system_clock::time_point a,b;

    std::tie(a,b) = std::minmax(a,b);
    if ((b-a) < std::chrono::seconds(2)) {

    }
}

Таким образом, вы знаете, что разница между временами на самом деле составляет менее 2 секунд, а не просто 2 такта часов, где такты вовсе не обязательно являются секундами.

К сожалению, для часов не существует std::abs, или вы просто напишите if (std::abs(b-a) < std::chrono::seconds(2))Хотя это достаточно легко написать свой собственный:

template<typename Rep,typename Period>
std::chrono::duration<Rep,Period> abs(std::chrono::duration<Rep,Period> d)
{
  return std::chrono::duration<Rep,Period>(std::abs(d.count()));
}
Другие вопросы по тегам