【问题标题】:How to subtract two time_t values (difftime returns double instead time_t)?如何减去两个 time_t 值(difftime 返回 double 而不是 time_t)?
【发布时间】:2018-01-18 18:07:22
【问题描述】:

time_t 这是平台相关类型。我找到了difftime,它以秒为单位返回差异,但我没有找到没有任何转换的简单减法函数。我如何知道标准并不能保证在整个时间连续体中始终如一,也没有告诉任何关于time_t 的编码。它也没有告诉两个不同的time_t 不会代表一个时刻。但在现实生活中我不确定。

time_t 数据类型是 ISO C 库中定义的数据类型 存储系统时间值。这些值是从标准返回的 time() 库函数。这种类型是定义在 标准标题。 ISO C 将 time_t 定义为算术类型, 但未指定任何特定类型、范围、分辨率或 为它编码。算术的含义也未指定 应用于时间值的操作。

Unix 和 POSIX 兼容系统将 time_t 实现为整数或 实浮点类型(通常是 32 位或 64 位整数) 表示自 Unix 纪元开始以来的秒数: UTC 时间 1970 年 1 月 1 日午夜(不包括闰秒)。一些 系统正确处理负时间值,而其他系统则不能。 使用带符号的 32 位 time_t 类型的系统容易受到年份的影响 2038问题。]

https://en.wikipedia.org/w/index.php?title=Time_t&oldid=450752800

我的意思是我需要time_t 作为回报:

time_t v1;
time_t v2;
time_t diff;

diff = some_substract_fct(v2, v1)

在没有difftime 的情况下比较/减去两个time_t 是否安全?例如:

time_t v1;
time_t v2;
time_t diff;

if (v2 > v1)
{
    ....
}

if (v2 == v1)
{
    ....
}

v3 = v2-v1;

改为

if (difftime(v2, v1) > 0)
{
}

if (difftime(v2, v1) == 0.0)
{
}

diff = some_substract_fct(v2, v1)

【问题讨论】:

  • 使用- 是不安全的,因为表示是特定于实现的,请参见此处:stackoverflow.com/a/13855956/8051589。这也适用于比较运算符,另见此处:stackoverflow.com/a/25198359/8051589。由于表示是实现定义的此时间戳值time_t 无法保存时间差。为什么双精度值不适合您?
  • 大多数实现(我目前使用的)将使用一个整数值,其中-<>!=== 将起作用。但这不能保证。
  • @Andre Kampling:因为我有一些任务管理器负责时间计算、操作、调度等,我想使用一种类型 (time_t) 而不进行任何转换。如果我需要时差,我会打电话给difftime。如果我需要解码time_t(带有时区处理),我会打电话给localtime。例如。添加到time_t 一些差异。是否真的需要将time_t 转换为tm 然后进行一些处理并将结果转换回time_t?我希望在没有转换的情况下以更微小的方式存在。例如。 time_t diff = some_fct(t2-t1)
  • time_t 是算术类型,因此减法本身不是问题。差异的符号当然是预期的,以后的时间有更大的价值。然而time_t 的规模和时代尚不清楚。建议将减法包装在辅助函数中。
  • 请注意,您需要使用@ 而不是2 才能将通知发送给个人(@Jonathan 有效,2Jonathan 无效)。

标签: c linux time


【解决方案1】:

引用 C11 标准:

7.27.2.4 time 函数

说明

时间函数确定当前日历时间。该值的编码未指定。

退货

时间函数返回当前日历时间的最佳近似值。如果日历时间不可用,则返回值(time_t)(-1)。如果timer不是空指针,则返回值也赋给它所指向的对象。

因此,您不能对time_t 值的编码或含义做出任何假设。不同的值可能表示相同的时间,与<等比较是没有意义的,与-的正则算术减法相同。

然而,在符合 POSIX 的系统上,time_t值(其类型仍未指定)表示自 1970 年 1 月 1 日 UTC 以来的秒数。因此,您可以将值与预期行为进行比较、减去和添加。在其他系统上,您可能需要使用系统特定函数以指定格式检索当前时间,或使用difftime() 以秒为单位计算时差。

另请注意,您的系统上可能还提供了另一个标准函数,它将以指定格式提供更准确的时间戳:

7.27.2.5 timespec_get 函数

概要

 #include <time.h>
 int timespec_get(struct timespec *ts, int base);

说明

timespec_get 函数设置 ts 指向的间隔,以根据指定的时基来保存当前的日历时间。 如果 base 是 TIME_UTC,则 tv_sec 成员设置为自实现定义的纪元以来的秒数,截断为整数,tv_nsec 成员设置为整数纳秒,四舍五入为分辨率系统时钟。

退货

如果timespec_get 函数成功,则返回非零值基数;否则返回零。

【讨论】:

  • timespec_get() 函数并非在任何地方都可用(例如,macOS Sierra 10.12.6 没有它)。尽管&lt;time.h&gt; 声明了它,但我的 Ubuntu 16.04 系统没有它的手册页条目(尽管我很愿意相信这是因为我缺少手册页而不是它没有记录)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
  • 2012-06-28
  • 2011-11-17
  • 2020-02-14
  • 2012-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多