【问题标题】:C++ Equivalent for GetLocalTime in Linux (with milliseconds!)Linux 中 GetLocalTime 的 C++ 等效项(以毫秒为单位!)
【发布时间】:2014-09-19 09:52:14
【问题描述】:

我已经搜索了一个多小时,但我似乎无法找到解决方案!

我正在寻找一个函数,它可以为我提供与 Windows 上的 GetLocalTime 类似的结构。对我来说重要的是这个结构有小时、分钟、秒和毫秒。

localtime() 不包括毫秒,因此我不能使用它!

我会欣赏使用标准库或其他非常小的库的解决方案,因为我正在使用 Raspberry Pi 并且不使用像 boost 这样的大型库!

【问题讨论】:

  • gettimeofday 怎么样?或者clock_gettime,如果您想要更高的精度?
  • FWIW,Windows 的GetLocalTime 函数不提供毫秒精度...wMilliseconds 字段只会在大约 15Hz 时更新(即,您在 ~66ms 内获得相同的值,然后查看接下来的 ~66ms 的值要大 ~66ms)。
  • @TonyD 这是一个普遍的问题。 Posix clock_gettime 函数返回纳秒,但也不能保证实际粒度接近纳秒。
  • @JamesKanze:当然,但是这个问题强调了实际毫秒精度的必要性 - “不包括毫秒,因此我不能使用它” - 所以我只是指点考虑到移植前的时机不是那么准确,因此这种需求可能不会那么强烈......
  • @TonyD 是的。鉴于此,将time 的结果乘以 1000 也不会差太多。

标签: c++ c linux time raspberry-pi


【解决方案1】:

如上所述,没有直接的等价物。如果您可以使用 C++ 11,<chrono> 标头允许获得相同的结果,但不能在单个调用中获得。您可以使用high_resolution_clock 获取当前Unix 时间(以毫秒为单位),然后您可以使用localtime C 函数获取不带毫秒的时间,并使用当前Unix 时间(以毫秒为单位)来查找毫秒数。看起来您必须编写自己的 GetLocalTime 实现,但使用 C++ 11 不会很复杂。

【讨论】:

  • 使用 C++ 11 进行编译需要更多时间(2 分钟对 10 秒)。所以我将使用其他解决方案。不过还是谢谢!
  • 这是你的选择,但对我来说程序运行时性能和可移植性很重要,编译性能根本不重要;您只需在 2 分钟内编译一次,而您的用户将使用它数月;)另一方面,C++ 11 功能比 Linux 系统调用更具可移植性。您可以为 Windows、Linux、MacOS 等提供一种功能实现,而不是使用系统调用/Windows API 进行条件编译(当然,如果您编写便携式软件)。
  • 如果你能提供至少一个最小的代码示例,我会节省至少 30 分钟的毫无意义的研究和试错。
【解决方案2】:

GetLocalTime 不是普通的 Linux 函数。

阅读time(7),你可能想要clock_gettime(2),或者(如Joachim Pileborg所评论的),旧的gettimeofday(2)

如果您需要一些 struct 给出所有小时、分钟、秒、毫秒,您必须使用 localtime(3) 自己编写代码并明确计算毫秒部分。

类似下面的代码以毫秒为单位打印时间

 struct timespec ts = {0,0};
 struct tm tm = {};
 char timbuf[64];
 if (clock_gettime(CLOCK_REALTIME, &ts))
    { perror("clock_gettime"), exit(EXIT_FAILURE);};
 time_t tim = ts.tv_sec;
 if (localtime(&tim, &tm))
    { perror("localtime"), exit(EXIT_FAILURE);};
 if (strftime(timbuf, sizeof(timbuf), "%D %T", &tm))
     { perror("strftime"), exit(EXIT_FAILURE);};
 printf("%s.%03d\n", timbuf, (int)(ts.tv_nsec/1000000));

【讨论】:

  • 调用 gettimeofday "older" 听起来好像不太好。但事实上,gettimeofday 已经在 Linux 上进行了积极优化,因此不需要调用内核空间。见man vdso。注意:这可能对 OP 没有帮助,因为我怀疑这种优化是在 Raspberry Pi 上实现的。
  • 这行得通!我使用的代码略有不同,但我使用的是相同的原理!
  • @flodin Posix 将 gettimeofday 记录为已过时,并表示要改用 clock_gettime
  • @JamesKanze 是的。您只需对对您的应用程序更重要的内容做出判断即可。不过,我怀疑 gettimeofday 会在未来 10 年内消失。同时,可能会对clock_gettime进行类似的优化。编辑:刚刚看到 Basile 的评论,所以请忽略我的 cmets。
【解决方案3】:

您可以使用以下组合:

  • clock_gettime(CLOCK_REALTIME);返回本地时间,最多毫秒(当然受实际时钟分辨率的限制);不关心本地时区信息,返回 UTC 时间。只需使用毫秒信息(来自tv_nsec 字段)。
  • time();返回本地时间,最多为秒 - 没有毫秒 - 也是 UTC 时间。 time() 结果(time_t)很容易转换为最终格式。

  • 然后使用localtime_r()转换time()结果;这建立了一个与 Windows SYSTEMTIME 非常相似的结构;结果最多为秒,并考虑到本地时区信息。

  • 最终使用clock_gettime()结果设置毫秒字段。

这些例程已记录在案,未弃用,可移植。
您可能需要调用tzset() 一次(这会设置时区信息 - 一个 C 全局变量 - 从操作系统环境 - 可能是一个繁重的操作)。

【讨论】:

    猜你喜欢
    • 2012-04-28
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多