2012-05-23 89 views
4

我试图用strftime功能当前UTC时间进行编码转换为字符串:得到使用的strftime()UTC时间戳

time_t now; 
struct tm nowLocal; 
struct tm nowUtc; 

now = time(NULL); 
localtime_r(&now, &nowLocal); 
gmtime_r(&now, &nowUtc); 

到目前为止好:nowLocal包含当前时间在我的时区(CET),nowUtc包含UTC时间,不同的是究竟根据tm_gmtoff值:

nowLocal: {tm_sec = 28, tm_min = 27, tm_hour = 13, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"} 

nowUtc: {tm_sec = 28, tm_min = 27, tm_hour = 11, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 0, tm_gmtoff = 0, tm_zone = 0x3e9907 "GMT"} 

然后我叫strftime()"%s"格式得到纪元以来的秒数:

char tsFromLocal[32]; 
char tsFromUtc[32]; 

strftime(tsFromLocal, sizeof(tsFromLocal), "%s", &nowLocal); 
strftime(tsFromUtc, sizeof(tsFromUtc), "%s", &nowUtc); 

结果对我来说似乎很奇怪。我期望从strftime()调用中得到完全相同的字符串,因为%s格式描述为:

自纪元以来的秒数,即从1970-01-01 00:00:00 UTC开始的秒数。除非有闰秒支持,否则闰秒不计算在内。

但是我有两个不同的值:

tsFromLocal:"1337772448" 

tsFromUtc: "1337768848" 

而且差异不tm_gmtoff),但。任何人都能解释这种行为吗或者它是一个错误?

我这样做的原因是我需要通过网络传输时间值,并将其与目标机器上可能处于不同时区的当前时间进行比较。在目标机器,我想:

struct tm restoredUtc; 
time_t restored; 

strptime(tsFromUtc, "%s", &restoredUtc); 
restored = timegm(&restoredUtc); 

但我得到:

restoredUtc:{tm_sec = 28, tm_min = 27, tm_hour = 12, tm_mday = 23, tm_mon = 4, tm_year = 112, tm_wday = 3, tm_yday = 143, tm_isdst = 1, tm_gmtoff = 7200, tm_zone = 0x8127a38 "CEST"} 

所以strptime()根据反正当前时区设置tm_zone。但是,即使我会使用的timelocal()代替timegm()我不会得到正确的值,因为它应该是11时27分28秒CEST,而不是12点27分28秒CEST。这个错误是否与strftime()的不同结果有关?

对此后续部分的任何评论?

+2

据我所知,'strftime()'将传递的时间结构解释为LOCAL TIME。由于原始'nowLocal'结构具有'tm_isdst = 1'(由前一次调用localtime_r()设置),因此您得到1小时的差异。如果在调用strftime之前将此字段设置为0,则可能会得到您期望的2小时差异。 – Claudix

+0

考虑到你从time()的结果中获得了时间,你可以将它与'strftime()'返回的结果进行比较,以确定哪个答案是正确的(如果有的话) 。我的猜测是当地时间是正确的,UTC是错误的。你是否可以让'strftime()'工作,因为你不想将TZ变量设置为'UTC0',然后调用'tzset()'就可以讨论了。 –

回答

2

你可能是最好的只是使用格林威治标准时间,因为有gmtime_r总是会给你所有地方相同的答案。如果一台机器想要在当地时间显示,可以稍后完成,但坚持一个时区进行存储和网络传输是一个好主意,并且GMT值很容易获得。

0

我怀疑评论是正确的:strftime()将时间解释为当地时间。请注意,tm_gmtoff不是一个标准化的字段;我想知道strftime()是否在看它。但我找不到任何具体的证实这一点。

但是,回答问题的第二部分,为什么不直接将time(NULL)的结果通过网络传输?或者,如果您已经有时间以struct tm的形式,请使用mktime()转换为time_t,然后将其转移? printf("%lu", (unsigned long) time)比试图使用strftime("%s")要简单得多,而C99或POSIX没有对其进行标准化。

0

Q1:任何人都可以解释这种行为吗?或者它是一个错误?

是的,这是一个错误,在tsFromLocal:"1337772448"!= tsFromUtc: "1337768848"。但是该错误位于tsFromUtc。他们应该是相同的,他们都应该是1337772448.

1337772448%(24 * 60 * 60) - > 41248是一天的UTC秒或11:27:28这与您的nowUtc结构匹配,并且是你认为它的时间(UTC)

Q2:...这个错误与strftime()的不同结果有关吗?

我同意使用time_t作为网络通信的整数。

是的,它是这样的。

如果您想进一步了解这篇文章:请考虑在time(&now)之后张贴now的数字值,并明确指出您当时的预期时间。