如何在C语言中将"2012-03-02"转换为Unix纪元时间?

8

我需要将一个表示2012年3月2日的字符串"2012-03-02"作为输入变量(char *)进行处理,将其转换为C编程语言中的Unix时间戳。

5个回答

4

本地时间还是协调世界时(UTC)?如果是 UTC,最简单的转换方法是完全避开 C 时间 API 并使用 POSIX 中自从纪元以来的秒数公式:

tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
    (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
    ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400

来源: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_15

如果是本地时间,由于time_t在非POSIX系统上不能保证以自纪元以来的秒数表示,并且很难计算与时代相对应的time_t值(因为mktime使用本地时间将不起作用),所以这个问题会变得非常棘手。然而,一旦你计算出自纪元以来的time_t值,只需使用mktime将解析的时间值转换为time_t,然后调用difftime即可。


tm_year 是当前年份减去 1900 年。 - rnrneverdies
那么使用results=results-tm_gmtoff进行重新调整,以使用时区偏移量如何?我认为这不是完全标准的C语言(而是扩展),但我现在已经测试过了,似乎可以正常工作。 - Sopalajo de Arrierez
@SopalajodeArrierez:如果你有tm_gmtoff,那么你几乎肯定拥有一个POSIX超集,然后你可以通过POSIX获得更好的、更可移植的解决方案。 - R.. GitHub STOP HELPING ICE
有没有其他公式/来源,我可以在其中使用tm_mon和tm_mday,而不是tm_yday? - Gow.
@Gow:是的,它需要一些与每个月天数的算术运算。如果您想了解详细信息,请将其作为新问题打开,并引用此问题。 - R.. GitHub STOP HELPING ICE
https://stackoverflow.com/questions/67532995/how-to-convert-date-into-epoch-timestamp-using-the-tm-mday-and-tm-mon-in-formula - Gow.

3

使用 sscanf 提取字符块,用提取的数据填充来自 <time.h>struct tm,最后使用 mktime 将其转换为 time_t

time_t ParseDate(const char * str)
{
    struct tm ti={0};
    if(sscanf(str, "%d-%d-%d", &ti.tm_year, &ti.tm_mon, &ti.tm_day)!=3)
    {
        /* ... error parsing ... */
    }
    ti.tm_year-=1900
    ti.tm_mon-=1
    return mktime(&ti);
}

你能说一下为什么我们需要从tm_year和tm_mon中分别减去1900和1吗? - Gow.
因为在 struct tm 中,年份从1900年开始计算,月份是从0开始计算的。您可以在文档中找到所有相关信息。 - Matteo Italia

2
C (POSIX)提供了一个函数来完成这个任务。使用strptime()将字符串转换为struct tm值。然后,您可以使用mktime()struct tm转换为time_t。请注意保留HTML标签。

2
那不是标准的C语言,而是POSIX。 - Matteo Italia

0
将其读入一个struct tm中,并调用mktime以获取您的time_t

0

这是我的解决方案:

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

int main(void) {
    time_t epoch;
    char timeString[80] = { "05 07 2021 00 33 51" }; 
    struct tm my_tm;
    char buffer[80];

    memset(&my_tm, 0, sizeof(my_tm));
    if (sscanf(timeString, "%d %d %d %d %d %d", &my_tm.tm_mon, &my_tm.tm_mday, &my_tm.tm_year, &my_tm.tm_hour, &my_tm.tm_min, &my_tm.tm_sec) != 6)
    {
        /* ... error parsing ... */
        printf(" sscanf failed");
        return 1;
    }
    my_tm.tm_isdst = -1;
    my_tm.tm_year -= 1900;
    my_tm.tm_mon -= 1;

    epoch = mktime(&my_tm);
    if (epoch == -1) {
        printf("Error: unable to make time using mktime\n");
    }
    else {
        strftime(buffer, sizeof(buffer), "%c", &my_tm);
        printf("%s  (epoch=%ld)", buffer, (long)epoch);
    }

    return(0);
}

注意:此代码将您提供的输入转换为“Fry May 7 00:33:51”和epoch = 1620340431,而不是您在注释中提到的那个(在Win10下使用MSVC运行)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接