如何在c中将datetime转换为unix时间戳?

时间:2009-06-16 16:20:56

标签: c unix datetime timestamp

场景是:我使用libexif以“YYYY-MM-DD HH:MM:SS”格式获取日期时间。为了最大限度地降低节省成本,我想将日期时间转换为unix时间戳或类似,仅花费64位或32位。 c有什么明确的方法吗?

6 个答案:

答案 0 :(得分:31)

您可以尝试strptimemktime

的组合
struct tm tm;
time_t epoch;
if ( strptime(timestamp, "%Y-%m-%d %H:%M:%S", &tm) != NULL )
  epoch = mktime(&tm);
else
  // badness

答案 1 :(得分:5)

将日期/时间的每个部分转换为整数以填充struct tm,然后使用mktime将其转换为time_t

答案 2 :(得分:1)

这是c /伪代码中的有线解决方案我刚刚一起入侵。祝你好运!

char * runner = NULL;
char *string_orig = "YYYY-MM-DD HH:MM:SS";
time_t time = 0;
struct tm tmp;

use strstr(string_orig, "-") and atoi foreach

  tmp->tm_year .. 
  tmp->tm_mon  .. 
  tmp->tm_mday ..  
  tmp->tm_hour  .. 
  tmp->tm_min  .. 
  tmp->tm_sec .. 

with *runner as help

time = mktime(&tm)

答案 3 :(得分:1)

sscanf怎么样?

struct tm tmVar;
char *strVar = "YYYY-MM-DD HH:MM:SS";
time_t timeVar;
if(sscanf(strVar, "%d-%d-%d %d:%d:%d", &tm.tm_year, /* the other fields */)==6)
    timeVar = mktime(&tmVar);
else
    // bad format

答案 4 :(得分:0)

当strptime不可用时,这是一个现成的片段:

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

time_t string_to_seconds(const char *timestamp_str)
{
    struct tm tm;
    time_t seconds;
    int r;

    if (timestamp_str == NULL) {
        printf("null argument\n");
        return (time_t)-1;
    }
    r = sscanf(timestamp_str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
    if (r != 6) {
        printf("expected %d numbers scanned in %s\n", r, timestamp_str);
        return (time_t)-1;
    }

    tm.tm_year -= 1900;
    tm.tm_mon -= 1;
    tm.tm_isdst = 0;
    seconds = mktime(&tm);
    if (seconds == (time_t)-1) {
        printf("reading time from %s failed\n", timestamp_str);
    }

    return seconds;
}

根据需要在sscanf中调整自己的字符串。要忽略时区并始终转换为GMT / UTC减法timezone(或_timezone)来自secondstimezone全局定义在time.h.DST已被忽略将tm_isdst的{​​{1}}字段归零。

答案 5 :(得分:0)

Linux支持getdate()功能,我认为这比直接调用strptime()更实用。这是因为getdate()函数会自动为您检查多种格式。它等同于在函数工作或测试所有格式之前调用strptime()各种格式。

// setenv() should be called only once
setenv("DATEMSK", "/usr/share/myprog/datemsk.fmt", 0);

// convert a date
struct tm * t1(getdate("2018-03-31 14:35:46"));
if(t1 == nullptr) ...handle error...
time_t date1(timegm(t1));

// convert another date
struct tm * t2(getdate("03/31/2018 14:35:46"));
if(t2 == nullptr) ...handle error...
time_t date2(timegm(t2));

注意:timegm()mktime()类似,不同之处在于它忽略了语言环境并使用了UTC。在大多数情况下,这是转换日期的正确方法。

datemsk.fmt文件至少包含这两种格式以支持上述日期:

%Y-%b-%d %H:%M:%S
%b/%d/%Y %H:%M:%S

支持的格式数量不受限制,但您可能不希望拥有太多。如果你有太多的格式,它会相当慢。您还可以动态管理格式并在循环中调用strptime()

Linux还提供了一个线程安全的getdate_r()函数。

手册页:http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html