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

时间:2021-10-23 11:26:48

the scenario is: I get datetime in format "YYYY-MM-DD HH:MM:SS" with libexif. To minimize the saving cost, I wanna convert the datetime to unix timestamp or alike which only cost 64bit or 32bit. Is there any explicit way with c?

场景是:我获得datetime格式为“yyyyy -MM- dd:MM:SS”和libexif。为了最小化节省的成本,我想将datetime转换为unix时间戳或类似的,只要64位或32位。c有什么明确的方法吗?

6 个解决方案

#1


30  

You could try a combination of strptime and mktime

您可以尝试组合strptime和mktime

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

#2


5  

Convert each part of the date/time into an integer to populate a struct tm, then convert that into a time_t using mktime.

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

#3


1  

Here is a wired solution in c/pseudo code I just hacked together. Good luck!

这是我刚刚破解的c/pseudo代码中的有线解决方案。好运!

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)

#4


1  

What about sscanf?

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

#5


0  

Here's a ready snippet when strptime is not available:

当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;
}

Adjust youself a string in sscanf to what you need. To ignore time zone and convert always as GMT/UTC substract a timezone (or _timezone) from seconds (timezone global is defined in time.h. DST is already ignored by zeroing tm_isdst field of tm.

在sscanf中调整你自己的字符串以满足你的需要。忽略时区,并始终将其转换为GMT/UTC从秒减去一个时区(时区全局定义为time.h)。DST已经被tm的tm_isdst字段归零所忽略。

#6


0  

Linux supports the getdate() function, which I think is more practical than calling strptime() directly. This is because the getdate() function automatically checks many formats for you. It is an equivalent to calling strptime() with various formats until the function works or all formats were tested.

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));

Note: timegm() is similar to mktime() except that it ignores the locale and uses UTC. In most cases that's the right way to convert your dates.

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

The datemsk.fmt file would include at least these two formats to support the above dates:

datemsk。fmt文件将至少包括这两种格式,以支持上述日期:

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

The number of supported formats is not limited, although you may not want to have too many. It's going to be rather slow if you have too many formats. You could also dynamically manage your formats and call strptime() in a loop.

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

Linux also offers a getdate_r() function which is thread safe.

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

Man Page: http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html

人页面:http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html。

#1


30  

You could try a combination of strptime and mktime

您可以尝试组合strptime和mktime

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

#2


5  

Convert each part of the date/time into an integer to populate a struct tm, then convert that into a time_t using mktime.

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

#3


1  

Here is a wired solution in c/pseudo code I just hacked together. Good luck!

这是我刚刚破解的c/pseudo代码中的有线解决方案。好运!

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)

#4


1  

What about sscanf?

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

#5


0  

Here's a ready snippet when strptime is not available:

当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;
}

Adjust youself a string in sscanf to what you need. To ignore time zone and convert always as GMT/UTC substract a timezone (or _timezone) from seconds (timezone global is defined in time.h. DST is already ignored by zeroing tm_isdst field of tm.

在sscanf中调整你自己的字符串以满足你的需要。忽略时区,并始终将其转换为GMT/UTC从秒减去一个时区(时区全局定义为time.h)。DST已经被tm的tm_isdst字段归零所忽略。

#6


0  

Linux supports the getdate() function, which I think is more practical than calling strptime() directly. This is because the getdate() function automatically checks many formats for you. It is an equivalent to calling strptime() with various formats until the function works or all formats were tested.

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));

Note: timegm() is similar to mktime() except that it ignores the locale and uses UTC. In most cases that's the right way to convert your dates.

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

The datemsk.fmt file would include at least these two formats to support the above dates:

datemsk。fmt文件将至少包括这两种格式,以支持上述日期:

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

The number of supported formats is not limited, although you may not want to have too many. It's going to be rather slow if you have too many formats. You could also dynamically manage your formats and call strptime() in a loop.

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

Linux also offers a getdate_r() function which is thread safe.

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

Man Page: http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html

人页面:http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html。