10

我有一个 struct tm
而且我需要在tm结构中添加一些固定的时间间隔(以 xx 年、xx 个月、xx 天为单位)。
是否有任何标准功能可以做到这一点?

我使用的编译器是 Windows XP 上的 MSVC 2005。

4

4 回答 4

11

有两个函数可以转换时间格式:

  1. mktime()struct tm(代表当地时间)转换为time_t.
  2. localtime()转换time_t为本地时间struct tm

有趣的是第一个,它接受超出范围的结构成员值,并作为转换的副产品适当地设置它们(和所有其他)。这可用于在算术运算之后校正字段数据值。但是字段的类型是 int,因此可能存在溢出(在 16 位系统上),例如,如果您添加一年中的秒数。

因此,如果您想获得实际日期,则此代码会有所帮助(来自@pmg 的修改后的答案副本):

struct tm addinterval(struct tm x, int y, int m, int d) {
    x.tm_year += y;
    x.tm_mon += m;
    x.tm_mday += d;
    mktime(&x);
    return x;
}

还要注意tm_isdst会员,关心它。当您跳过夏令时切换日期时,它的值可能会导致时间来回移动。

于 2010-11-18T12:57:15.013 回答
10

标准加法运算符有效。

struct tm x;
/* add 2 years and 3 days to x */
x.tm_year += 2;
x.tm_mday += 3;

编辑:您可以轻松地制作一个功能

struct tm addinterval(struct tm x, int y, int m, int d) {
    x.tm_year += y;
    x.tm_mon += m;
    x.tm_mday += d;
    mktime(&x); /* normalize result */
    return x;
}

编辑:添加mktime到标准化结果

于 2010-11-18T11:54:49.507 回答
0

我建议先将手头的日期转换为天数。那么添加一个间隔是微不足道的。然后,将数字转换回日期。

您可以在http://alcor.concordia.ca/~gpkatch/gdate-algorithm.html找到将日期转换为天数并返回的算法

于 2010-11-18T13:19:32.390 回答
0

其他答案会导致高度不稳定的结果,具体取决于您的系统如何初始化 struct tm 以及中午时间值是否已正确初始化。

如果您只关心日期的变化,而时间保持不变,则在传递到 之前将tm_isdst, tm_hour, tm_secall 设置为 0 mktime。更好的是,在之前获取它们的值并在之后重置它们以保持一致性(如果它们之前不一致,它们将始终保持不变)。重用其他答案的代码:

tm addinterval(tm t, int y, int m, int d)
{
    auto hour = t.tm_hour;
    auto min = t.tm_min;
    auto sec = t.tm_sec;

    // First we discover the DST Flag. By setting hour to 12
    //   we can assure the mktime does not shift the date
    //   because it will shift the hour!
    t.tm_isdst = 0;
    t.tm_hour = 12;
    t.tm_min = 0;
    t.tm_sec = 0;
    mktime(&t);

    // Now we can add the interval
    t.tm_year += y;
    t.tm_mon += m;
    t.tm_mday += d;
    mktime(&t);

    // Now reset the mid-day time values
    t.tm_hour = hour;
    t.tm_min = min;
    t.tm_sec = sec;

    // Return struct tm while keeping mid-day time the same
    //   while the only values that changed are the date and perhaps isdst.
    return t;
}

我希望它更简单,但这就是必须的。

于 2017-08-30T15:41:39.983 回答