【问题标题】:Checking if time_t is between other time_t with some margin of error检查 time_t 是否在其他 time_t 之间并有一定的误差
【发布时间】:2012-06-06 19:42:20
【问题描述】:

我有两个 time_t 变量:timeA 和 timeB。

我想要做的是检查 timeA 是否与 timeB 相同。但是,我知道在某些情况下它们不会完全相同,并且它们两者之间可能存在 1 或 2 秒的差异,所以我真正要检查的是:

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

有可能吗?

我想一种选择是不使用 time_t,而是将 timeB 保留为 tm 结构,并且在比较之前,减去两秒并创建 time_t timeBminus,然后添加四秒并创建 time_t timeBplus。问题是我将比较数百万个 timeA - timeB 对,并希望使其尽可能简单和快速。

我该怎么做?

【问题讨论】:

  • 你应该试试看它是否有效:)

标签: c++ time-t


【解决方案1】:

类似的东西-

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

(无法从这里检查确切的类型等,但我认为这个想法是正确的)

【讨论】:

  • +1,虽然我会使用 std::absdouble 重载而不是 C 风格的 fabs
  • 确实,我知道有类似的东西,但我无法轻松检查调用的功能(从手机发布...)
  • 谢谢。现在看起来很明显!
  • 确实,但是difftime的结果是
  • 警告:int abs(int)long abs(long)float fabs(float)double fabs(double)long double fabs(long double) => 即使在 C++ 中它仍然是 fabs :(
【解决方案2】:

尽管time_t 通常表示秒,但实际上它不是标准行为。 time_t的细节留待实现(根据this

不要直接使用time_ts,最好使用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;
}

【讨论】:

    【解决方案3】:
    if(abs(timeA - timeB) <= 2) {
      // yay!
    }
    

    【讨论】:

    • 对于 2.0 秒的余量,此答案假定 time_t 分辨率为秒。一种常见的情况,但不便携。
    【解决方案4】:

    如果你的编译器支持 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) &lt; 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()));
    }
    

    【讨论】:

    • 另一个我不知道的 c++ 新特性。我知道所有大功能,但似乎错过了所有小功能。
    猜你喜欢
    • 2017-01-04
    • 2012-03-31
    • 2017-08-04
    • 2017-06-04
    • 2023-03-18
    • 2013-11-22
    • 2011-11-17
    • 2016-08-11
    • 2015-10-07
    相关资源
    最近更新 更多