簡體   English   中英

如何將日期時間轉換為 c 中的 unix 時間戳?

[英]how to convert datetime to unix timestamp in c?

場景是:我使用 libexif 獲取格式為“YYYY-MM-DD HH:MM:SS”的日期時間。 為了盡量減少節省成本,我想將日期時間轉換為 unix 時間戳或類似的時間戳,只需 64 位或 32 位。 c 有什么明確的方法嗎?

您可以嘗試結合使用strptimemktime

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

將日期/時間的每個部分轉換為 integer 以填充struct tm ,然后使用mktime將其轉換為time_t

這是我剛剛一起破解的 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)

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

當 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,請從seconds中減去timezone (或_timezone )( timezone全局在 time.h 中定義。DST 已通過將tmtm_isdst字段置零而被忽略。

Linux支持getdate() function,我覺得比直接調用strptime()更實用。 這是因為getdate() function 會自動為您檢查多種格式。 它等同於以各種格式調用strptime() ,直到 function 工作或所有格式都經過測試。

// 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() function。

手冊頁: http://pubs.opengroup.org/onlinepubs/7908799/xsh/getdate.html

對於使用 gcc 的任何人,以下代碼對我有用:

#define YEAR_OFFSET 1900

struct tm* dt = (struct tm*)malloc(sizeof(struct tm));
char *strVar = "2022-08-13 23:09:47"; //! "YYYY-MM-DD HH:MM:SS"
time_t timeVar;
if(sscanf(strVar, "%d-%hhd-%hhd %hhd:%hhd:%hhd", &dt->tm_year, &dt->tm_mon, &dt->tm_mday, &dt->tm_hour, &dt->tm_min, &dt->tm_sec)==6)
{
    dt->tm_year -= YEAR_OFFSET;
    dt->tm_mon -= 1;
    timeVar = mktime(&tmVar);
}
else
    ;// bad format
free(dt);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM