シナリオは次のとおりです。libexifを使用して「YYYY-MM-DD HH:MM:SS」の形式で日時を取得します。節約コストを最小限に抑えるために、日時をUNIXタイムスタンプなど、64ビットまたは32ビットのみのコストに変換します。 cで明示的な方法はありますか?
日付/時刻の各部分を整数に変換してstruct tm
に入力し、次に mktime を使用してtime_t
に変換します。
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
これが私がハッキングした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)
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
)from seconds
(timezone
グローバルはtime.hで定義されています。DSTはゼロ化によってすでに無視されていますtm_isdst
tm
のフィールド。
Linuxはgetdate()
関数をサポートしており、strptime()
を直接呼び出すよりも実用的だと思います。これは、getdate()
関数が自動的にmany形式をチェックするためです。これは、関数が機能するか、すべての形式がテストされるまで、さまざまな形式で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()
は、ロケールを無視してUTCを使用することを除いて、mktime()
に似ています。ほとんどの場合、これは日付を変換する正しい方法です。
Datemsk.fmtファイルには、上記の日付をサポートするために、少なくとも次の2つの形式が含まれます。
_%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