如果我有这个字符串:
2011-10-08T07:07:09Z
是否可以从中获得time_t
?如果是这样,怎么办呢?
答案 0 :(得分:4)
是的,确实如此。首先,使用strptime(3)
将其转换为细分时间。这会给你一个struct tm
,这是一个分解时间的结构类型。
从那里,您可以使用time_t
转换为mktime(3)
。
以下是一个例子:
#define _XOPEN_SOURCE
#include <time.h>
#include <stdio.h>
#include <string.h>
int main(void) {
const char *date_example = "2011-10-08T07:07:09Z";
struct tm broken_down;
memset(&broken_down, 0, sizeof(broken_down));
strptime(date_example, "%Y-%m-%dT%H:%M:%SZ", &broken_down);
broken_down.tm_isdst = 0; // Indicates that DST is not in effect
time_t epoch_time = mktime(&broken_down);
// Note: this is platform dependent
printf("Epoch time: %lld\n", (long long) epoch_time);
return 0;
}
答案 1 :(得分:1)
使用sscanf()
来分解时间。诀窍是以某种方式确定本地和通用时间之间的差异,因此代码可以调用mktime()
- 使用假定struct tm
是本地时间..
#include <time.h>
#include <stdio.h>
int Get_TZ_delta(const struct tm *tmptr) {
// Make local copy
struct tm tm = *tmptr;
time_t t = mktime(&tm);
struct tm utc_tm = *gmtime(&t);
time_t t2 = mktime(&utc_tm);
return (int) difftime(t, t2);
}
time_t UniversalTimeStamp_to_time_t(const char *ts) {
struct tm tm = { 0 };
// Use a sentinel to catch extra garbage
char sentinel;
if (sscanf(ts, "%d-%2d-%2dT%2d:%2d:%2dZ%c", &tm.tm_year, &tm.tm_mon,
&tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &sentinel) != 6) {
return -1;
}
// struct tm uses offset from 1900 and January is month 0
tm.tm_year -= 1900;
tm.tm_mon--;
// Convert tm from UCT to local standard time
tm.tm_isdst = 0;
tm.tm_sec += Get_TZ_delta(&tm);
time_t t = mktime(&tm); // mktime() assumes tm is local
// test code
{
printf("UTC `%s`\n", ts);
char buf[100];
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S %Z", &tm);
printf("Local %s\n", buf);
printf("Unix %lld\n\n", (long long) mktime(&tm));
}
return t;
}
int main(void) {
UniversalTimeStamp_to_time_t("2015-06-18T22:07:52Z");
UniversalTimeStamp_to_time_t("2011-10-08T07:07:09Z");
UniversalTimeStamp_to_time_t("1970-01-01T00:00:00Z");
return 0;
}
输出
UTC `2015-06-18T22:07:52Z`
Local 2015-06-18T17:07:52 CDT
Unix 1434665272
UTC `2011-10-08T07:07:09Z`
Local 2011-10-08T02:07:09 CDT
Unix 1318057629
UTC `1970-01-01T00:00:00Z`
Local 1969-12-31T18:00:00 CST
Unix 0
答案 2 :(得分:1)
另一种方法应该是代码知道time_t
是自1970年1月1日0:00:00以来的秒数。使用sscanf()
来解析字符串,计算天数,然后返回秒数。
#include <time.h>
#include <stdio.h>
#define MARCH 3
#define DaysPer400Years (400*365LL + 97)
#define DaysPer100Years (100*365LL + 24)
#define DaysPer4Years (4*365LL + 1)
#define DaysPer1Year 365LL
#define DayNumber1970Jan1 719469LL
long long DayNumber(int year, int Month, int Day, long epoch) {
long long dn = Day;
long long y = year;
y += Month / 12;
Month %= 12;
while (Month < MARCH) {
Month += 12;
y--;
}
// And then a miracle occurs.
dn += ((Month - MARCH) * (7832 / 4) + (140 / 4)) >> (8 - 2);
dn += (y / 400) * DaysPer400Years;
y %= 400;
dn += (y / 100) * DaysPer100Years;
y %= 100;
dn += (y / 4) * DaysPer4Years;
y %= 4;
dn += y * DaysPer1Year;
return dn - epoch;
}
time_t UniversalTimeStamp_to_time_t(const char *ts) {
int y,m,d,H,M,S;
// Use a sentinel to catch extra garbage
char sentinel;
if (sscanf(ts, "%d-%2d-%2dT%2d:%2d:%2dZ%c", &y, &m,
&d, &H, &M, &S, &sentinel) != 6) {
return -1;
}
long long t = DayNumber(y, m, d, DayNumber1970Jan1);
t = t*24L*60*60 + 3600L*H + 60*M + S;
// test code
{
printf("UTC `%s`\n", ts);
time_t tt = t;
struct tm tm = *gmtime(&tt);
char buf[100];
strftime(buf, sizeof buf, "%Y-%m-%dT%H:%M:%S %Z", &tm);
printf("Local %s\n", buf);
printf("Unix %lld\n\n", t);
}
return t;
}
int main(void) {
UniversalTimeStamp_to_time_t("2015-06-18T22:07:52Z");
UniversalTimeStamp_to_time_t("2011-10-08T07:07:09Z");
UniversalTimeStamp_to_time_t("1970-01-01T00:00:00Z");
return 0;
}
输出
UTC `2015-06-18T22:07:52Z`
Local 2015-06-18T22:07:52
Unix 1434665272
UTC `2011-10-08T07:07:09Z`
Local 2011-10-08T07:07:09
Unix 1318057629
UTC `1970-01-01T00:00:00Z`
Local 1970-01-01T00:00:00
Unix 0