【问题标题】:How do I convert "2012-03-02" into unix epoch time in C?如何在 C 中将“2012-03-02”转换为 unix 纪元时间?
【发布时间】:2012-03-21 11:40:26
【问题描述】:

代表 2012 年 3 月 2 日的字符串“2012-03-02”作为输入变量 (char *) 提供给我。

如何在 C 编程语言中将此日期转换为 unix 纪元时间?

【问题讨论】:

    标签: c datetime date time


    【解决方案1】:

    当地时间还是 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

    如果是本地时间,问题会变成地狱,因为除 POSIX 系统外,time_t 不能保证表示为自纪元以来的秒数,而且很难计算 time_t 值对应于时代(mktime 将不起作用,因为它使用本地时间)。但是,一旦您计算出该纪元的 time_t,只需使用 mktime 作为您解析的时间值,然后调用 difftime

    【讨论】:

    • tm_year 是当前年份 - 1900。
    • results=results-tm_gmtoff 使用时区偏移量重新调整怎么样?我认为它不是一个完全标准的 C(而是一个扩展),但我现在已经对其进行了测试,它似乎工作正常。
    • @SopalajodeArrierez:如果您拥有 tm_gmtoff,那么您几乎可以肯定拥有 POSIX 超集,然后通过 POSIX 获得更好、更便携的解决方案。
    • 是否有任何其他公式/来源可以代替 tm_yday,我可以使用 tm_mon 和 tm_mday?
    • @Gow:是的,它需要一些算术运算,每个月的天数。如果您想了解详细信息,可以将其作为一个新问题打开,参考这个问题。
    【解决方案2】:

    使用sscanf 提取片段,使用提取的数据填充struct tm(来自<time.h>),最后使用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 吗?
    • 因为在struct tm 中,年份从 1900 开始,月份从 0 开始。您可以在文档中找到所有相关信息。
    【解决方案3】:

    C (POSIX) 为此提供了一个函数。使用strptime() 将字符串转换为struct tm 值。然后,您可以使用mktime()struct tm 转换为time_t

    【讨论】:

    • 这不是标准的,C,它是 POSIX。
    【解决方案4】:

    将其读入struct tm 并致电mktime 以获取您的time_t

    【讨论】:

      【解决方案5】:

      这是我的解决方案:

      #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,这不是您在评论中提到的那个(使用 MSVC 在 Win10 下运行)

      【讨论】:

        猜你喜欢
        • 2016-01-20
        • 2014-04-07
        • 2012-01-30
        • 2021-08-11
        • 1970-01-01
        • 1970-01-01
        • 2015-05-20
        • 2021-07-09
        • 2015-07-08
        相关资源
        最近更新 更多