【问题标题】:utc seconds since midnight to datetimeUTC 从午夜到日期时间的秒数
【发布时间】:2012-10-03 06:43:44
【问题描述】:

我将雷达数据作为“轨迹”获取,轨迹数据显然表示自上次午夜以来的 UTC 秒数。这不是自 1970 年 1 月 1 日以来的秒数。

现在我想将其转换为日期时间,因为我知道计算机上的时钟可能与雷达上的时钟略有不同步。我假设雷达的秒是参考,而不是计算机的。 我想将这些秒数转换为完整的日期时间。事情似乎有点棘手 午夜。

有什么建议吗?我有一些想法,但我不想错过任何东西。

我正在使用 C++ Qt。

【问题讨论】:

    标签: c++ qt datetime utc


    【解决方案1】:
    //  Function to extend truncated time, given the wall time and period, all
    //  in units of seconds.
    //
    //  Example: Suppose the truncated period was one hour, and you were
    //  given a truncated time of 25 minutes after the hour. Then:
    //
    //  o Actual time of 07:40:00 results in 07:25:00 (07:40 + -15)
    //  o Actual time of 07:10:00 results in 07:25:00 (07:10 + +15)
    //  o Actual time of 07:56:00 results in 08:25:00 (07:56 + +29)
    
    double extendTruncatedTime(double trunc, double wall, int period) {
       return wall + remainder(trunc - wall, period);
    }
    
    #define extendTruncatedTime24(t) extendTruncatedTime(t, time(0), 24 * 60 * 60)
    

    一些评论:

    • wall 的单位是秒,但它的底数可以是任意的。在 Unix 中,它通常从 1970 年开始。

    • 闰秒在这里不相关。

    • remainder() 需要 #include <math.h>。

    • 根据 OP 的要求,extendTruncatedTime() 中的 period 几乎总是 24 小时,24 * 60 * 60。也就是说,给定一天中的时间,它会根据“墙”时间通过添加年、月和日来扩展它。

    • 我知道上一条语句的唯一例外是,因为你提到雷达,在 Asterix CAT 1 数据项 I001/141 中,周期为 512 秒,而给定的 extendTruncatedTime() 没有不太好用。

    • 还有一个extendTruncatedTime() 没有涵盖的重要案例。假设给你一个截断的时间,由月中的日期、小时和分钟组成。年月怎么填?

    以下代码 sn-p 将年份和月份添加到从 DDHHMM 格式派生的时间:

    time_t extendTruncatedTimeDDHHMM(time_t trunc, time_t wall) {
       struct tm retval = *gmtime_r(&trunc, &retval);
       struct tm now    = *gmtime_r(&wall,  &now);
       retval.tm_year = now.tm_year;
       retval.tm_mon  = now.tm_mon;
       retval.tm_mon += now.tm_mday - retval.tm_mday >  15; // 15 = half-month
       retval.tm_mon -= now.tm_mday - retval.tm_mday < -15;
       return timegm(&retval);
    }
    

    正如所写,这不会处理错误输入。例如,如果今天是 7 月 4 日,那么毫无意义的 310000 将悄悄地转换为 7 月 1 日。 (这可能是一个特性,而不是一个错误。)

    【讨论】:

      【解决方案2】:

      如果您可以链接到另一个库,我建议您使用boost::date_time。

      您似乎想从午夜(纪元)开始以秒为单位获取当前日期,然后将雷达时间添加到其中,然后将总和转换回日期时间,并将其转换为字符串。

      使用 boost 将帮助您:

      • 获取正确的当地时间
      • 计算返回日期
      • 将漂移纳入计算中
      • 考虑闰秒

      因为您可以使用时间间隔和持续时间等概念。您可以使用类似(来自 boost 示例):

      ptime t4(date(2002,May,31), hours(20)); //4 hours b/f midnight NY time
      ptime t5 = us_eastern::local_to_utc(t4);
      std::cout << to_simple_string(t4) << " in New York is " 
                << to_simple_string(t5) << " UTC time "
                << std::endl;
      

      如果你想手动计算漂移,你可以很容易地做时间数学,类似于这样的结构:

       ptime t2 = t1 - hours(5)- minutes(4)- seconds(2)- millisec(1);
      

      【讨论】:

      • 是的,但是你如何解释这样一个事实,即每天有几分钟,运行代码的计算机可能与雷达的日期不同。
      • 如果时钟有漂移,它必须与协议同步,例如NTP。除非想要手动同步,这只是意味着以固定的时间间隔测量漂移并计算平均漂移的偏移量。如果漂移如此之大以至于它推进到第二天,可以将其纳入计算并减去。毕竟构建时间是在用户端完成的。一旦时间算术正确,恕我直言,这将通过使用 boost 来解决。
      猜你喜欢
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 2012-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多