2012-05-23 5 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"} 

을 그럼 난 시대 이후 초를 얻을 수 "%s" 형식 strftime() 전화 :

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초하지 중부 유럽 표준시 12시 27분 28초해야하지만 나는 올바른 값을받지 않습니다. 이 오류가 strftime()의 다른 결과와 관련이 있습니까?

이 부분에 대한 모든 설명?

+2

필자가 아는 한,'strftime()'은 전달 된 시간 구조를 LOCAL TIME으로 해석합니다. 원래'nowLocal' 구조체가'tm_isdst = 1' (localtime_r()에 대한 이전 호출에 의해 설정 됨)을 가지므로 1 시간 차이가납니다. strftime을 호출하기 전에이 필드를 0으로 설정하면 예상 한 시간의 차이를 얻을 수 있습니다. – Claudix

+0

'time()'의 결과에서 신기원으로부터의 시간을 초 단위로 볼 때,'strftime()'이 리턴 한 것과 그 값을 비교해 볼 수있다. . 내 생각 엔 현지 시간이 정확하고 UTC가 잘못되었다는 것입니다. 'strftime()'을 TZ 변수를'UTC0'으로 설정하고,'tzset()'을 호출하는 것이 부족한 것처럼 동작하게 할 수 있는지 여부는 논의를 위해 열려 있습니다. –

답변

2

GMT를 사용하는 것이 가장 좋을 것입니다. 항상이있어 어디에서나 동일한 대답을 줄 수 있습니다. 개별 컴퓨터가 현지 시간으로 표시하려고하는 경우 나중에 수행 할 수 있지만 저장 및 네트워크 전송을 위해 하나의 시간대를 고수하는 것이 좋습니다. 그리니치 표준시 값은 쉽게 얻을 수 있습니다.

0

의견이 정확하다고 생각됩니다. strftime()은 현지 시간으로 시간을 해석합니다. tm_gmtoff은 표준화 된 필드가 아닙니다. strftime()도보고 있는지 궁금합니다. 그러나 나는 이것을 확인하기 위해 구체적인 것을 발견 할 수 없다.

그러나 질문의 ​​두 번째 부분에 답하는 이유는 네트워크를 통해 time(NULL)의 결과를 직접 전송하는 것이 가장 좋은 이유는 무엇입니까? 또는 이미 시간이 struct tm 인 경우 mktime()을 사용하여 time_t으로 변환 한 다음 전송 하시겠습니까? printf("%lu", (unsigned long) time)은 C99 또는 POSIX로 표준화되지 않은 strftime("%s")을 사용하는 것보다 훨씬 간단합니다.

0

질문 : 아무도 그러한 행동을 설명 할 수 있습니까? 아니면 버그입니까?

예,이 버그는 tsFromLocal:"1337772448"! = tsFromUtc: "1337768848"입니다. 그러나 버그는 tsFromUtc에 있습니다. 서로 같아야하며 둘 다 1337772448이어야합니다.

1337772448 % (24 * 60 * 60) -> 41248은 (는) nowUtc 구조와 일치하는 오늘의 초 또는 11:27:28의 초이며, (UTC 기준)

Q2 : ...이 오류는 strftime()의 다른 결과와 관련이 있습니까?

네트워크 통신을위한 정수로 time_t을 사용하는 일반적인 아이디어에 동의합니다.

예, 그렇습니다.

now의 숫자 값을 time(&now) 바로 뒤에 게시하고 예상 한 시간이 명확하게 명시된 것을 고려해보십시오.