Проверка, находится ли 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;
}
Если ваш компилятор поддерживает 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()));
}