C struct tm时间-添加小时数

C struct tm时间-添加小时数,c,time,C,Time,我有表示时间1900-01-01 00:00:00的struct tm。如何在小时内添加偏移量?例如,我有以小时为单位的偏移量—大约值1048621。119.7年。假设生成的日期/时间落在时间t表示的范围内,您可以将小时偏移量添加到tm::tm\u hour中,然后调用mktime进行标准化 #include <time.h> #include <stdio.h> int main() { struct tm t = { 0 }; t.tm_mday =

我有表示时间1900-01-01 00:00:00的struct tm。如何在小时内添加偏移量?例如,我有以小时为单位的偏移量—大约值1048621。119.7年。

假设生成的日期/时间落在时间t表示的范围内,您可以将小时偏移量添加到tm::tm\u hour中,然后调用mktime进行标准化

#include <time.h>
#include <stdio.h>

int main()
{
    struct tm t = { 0 };
    t.tm_mday = 1;  // Jan 1st 1900

    t.tm_hour = 1048621;
    if(mktime(&t) == -1) return 1;

    printf("%d-%02d-%02d %02d:%02d:%02d\n",
           t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
           t.tm_hour, t.tm_min, t.tm_sec);

    return 0;
}
[编辑]正如评论中指出的,上述mktime调用在MSVC中失败。事实证明,微软的mktime实现对tm参数进行了预检查,如果tm_year<69,则无条件失败,甚至没有查看其他tm字段。虽然如果结束日期/时间超出范围,特别是如果它早于纪元的开始(通常是1970年1月1日),预计将失败,但通常应在重整化后进行此类检查

下面是添加范围验证的更新代码,已验证可与和一起使用


假设生成的日期/时间落在时间t表示的范围内,您可以将小时偏移量添加到tm::tm_hour,然后调用mktime进行规范化

#include <time.h>
#include <stdio.h>

int main()
{
    struct tm t = { 0 };
    t.tm_mday = 1;  // Jan 1st 1900

    t.tm_hour = 1048621;
    if(mktime(&t) == -1) return 1;

    printf("%d-%02d-%02d %02d:%02d:%02d\n",
           t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
           t.tm_hour, t.tm_min, t.tm_sec);

    return 0;
}
[编辑]正如评论中指出的,上述mktime调用在MSVC中失败。事实证明,微软的mktime实现对tm参数进行了预检查,如果tm_year<69,则无条件失败,甚至没有查看其他tm字段。虽然如果结束日期/时间超出范围,特别是如果它早于纪元的开始(通常是1970年1月1日),预计将失败,但通常应在重整化后进行此类检查

下面是添加范围验证的更新代码,已验证可与和一起使用


将结构转换为统一的整数时间戳,然后将小时转换为与时间戳相同的单位,并将它们相加。转换回tm结构。处理时间和日期真的没有简单易行的方法。我能用timegm和time\u t来处理这个问题吗?因为UNIX时间戳从1970年开始。请将结构转换为统一的整数时间戳,然后将小时转换为与时间戳相同的单位,并将它们相加。转换回tm结构。处理时间和日期真的没有简单易行的方法。我能用timegm和time\u t来处理这个问题吗?因为UNIX时间戳从1970年开始。在Visual Studio中,它不起作用,并且时间在mktime之后不会更改。mktime的返回值为-1@MartinPerry我编辑了签入时的错误。应该对超出范围的值进行重新规范化,1048621肯定适合整数。我必须查看MSVC的CRT源才能找到它。@MartinPerry MSVC的mktime将无条件失败,如果tm_year<69,甚至在查看其他tm字段之前,这就解释了错误。但我不知道这是一种顺从的行为。我猜可以为MSVC编码一个变通方法,使用tm_year=70和tm_hour=1048621-magic_const。MartinPerry发现MSVC在mktime上还有第二个怪癖,即使在tm_isdst=0时,本地DST也会被考虑在内。上面更新的代码在gcc中的工作原理相同,没有t.tm_isdst=-1;行,但在MSVC中需要它,或者,MSVC中的另一种替代方法是使用非标准的_mkgmtime。在Visual Studio中,它不工作,并且时间在mktime之后不会更改。mktime的返回值为-1@MartinPerry我编辑了签入时的错误。应该对超出范围的值进行重新规范化,1048621肯定适合整数。我必须查看MSVC的CRT源才能找到它。@MartinPerry MSVC的mktime将无条件失败,如果tm_year<69,甚至在查看其他tm字段之前,这就解释了错误。但我不知道这是一种顺从的行为。我猜可以为MSVC编码一个变通方法,使用tm_year=70和tm_hour=1048621-magic_const。MartinPerry发现MSVC在mktime上还有第二个怪癖,即使在tm_isdst=0时,本地DST也会被考虑在内。上面更新的代码在gcc中的工作原理相同,没有t.tm_isdst=-1;行,但在MSVC中需要它,或者,MSVC中的另一种替代方法是使用非标准的_mkgmtime。
#include <time.h>
#include <limits.h>
#include <stdio.h>

int main()
{
    const int tmYear1970 = 70;
    const int tmDay1970 = tmYear1970 * 365 + tmYear1970 / 4; //      25568
    const int tmHour1970 = tmDay1970 * 24;                   //     613632
    const int tmHourMax = INT_MAX - tmHour1970;              // 2146870015

    int tmHour = 1048621;
    if(tmHour < tmHour1970 || tmHour > tmHourMax) return 2;

    struct tm t = { 0 };
    t.tm_mday = 1; // Jan 1st 1900 12 AM

    t.tm_year = tmYear1970;
    t.tm_hour = tmHour - tmHour1970;
    t.tm_isdst = -1;
    if (mktime(&t) == -1) return 1;

    printf("%d-%02d-%02d %02d:%02d:%02d\n",
           t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
           t.tm_hour, t.tm_min, t.tm_sec);

    return 0;
}