2014-07-25 1 views
3

gcc 컴파일러를 사용하여 RedHat Linux 컴퓨터에 C 프로그램을 작성했습니다. gcc 컴파일러는 두 날짜를 입력으로 받아들이고 차이점을 계산합니다.mktime()이 이상한 날짜 변경

그러나 아래의 코드 세그먼트와 같이 mktime()과 같이 이상한 동작이 발견되었습니다.

struct tm t; 
t.tm_year=4; 
t.tm_mon=9; 
t.tm_mday=30; 
t.tm_hour=0; 
t.tm_min=0; 
t.tm_sec=0; 

printf("%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon, t.tm_day, t.tm_hour, t.tm_min, t.tm_sec); 
//result: 4-9-30 0:0:0, which means 1904 Oct 30 00:00:00 

mktime(&t); 

printf("%d-%d-%d %d:%d:%d\n", t.tm_year, t.tm_mon, t.tm_day, t.tm_hour, t.tm_min, t.tm_sec); 
//result: 4-9-29 23:36:36, which means 1904 Oct 29 23:36:36 

당신이 struct tm가 부당 보이는 mktime() 후 이동했다 볼 수 있듯이


.

많은 테스트를했는데, 이상한 동작이 1904 년 10 월 30 일 00:00:00 - 00:23:24 사이의 날짜 지정에서만 발생한다는 것을 알았습니다.

게다가, 나는 유닉스 서버 (HP-UX)에서 동일한 코드를 테스트했으며, 아무런 변화없이 완벽하게 실행된다.

누가 비슷한 경험을했는지 궁금합니다. 어떤 일이 벌어지고 있는지에 대한 힌트를 줄 수 있습니까?

저는 홍콩 시간대를 사용하고 있습니다.

+0

시간대가 무엇입니까? –

+1

'아시아/홍콩'및 다른 홍콩 시간대에 대해서만 이것을 재현 할 수 있습니다. – Frxstrem

+0

'tm_day를'tm_day로 철자가 잘못되었습니다. 실제 컴파일 가능한 코드를 복사하여 붙여 넣는 것이 항상 (거의) 가장 좋습니다. –

답변

6

mktime() 함수는 입력이 로컬 시간을 나타내는 것으로 가정합니다. 다양한 장소에서 현지 시간으로 여러 번 이상한 교대가있었습니다.

시간대를 아는 것이 도움이됩니다. 시간대를 UTC로 설정하면 문제가 사라질 것으로 판단됩니다.

본인은이 문제가 직접 보이지 않습니다 (태평양 표준시 기준 세계 표준시 (UTC) 서쪽 7 시간).

같은 해 6 월 룩셈부르크에서의 시간 이동과 비슷합니다. here, 로컬 시계가 35 분 24 초 앞으로 이동했을 때로 나타납니다. 1904 년 10 월 30 일이 일요일이었고, 이는 그러한 변화의 가능성이있는시기입니다.

또한 1927 년 상하이에서 시간 변경에 관한 내용 (Jon Skeet의 가장 높은 점수를 얻은 답변이 있음)을 참조하십시오.

업데이트 : Frxstrem 님의 의견에 감사드립니다. 1904 년 10 월 30 일 홍콩에서 HKT에서 LMT로 시간이 변경되었습니다. (a) 시간대가 홍콩 시간으로 설정되어 있고 (b) 시스템의 시간대 라이브러리가이 특정 변경 사항을 반영 할 정도로 상세하게 표시되면 증상이 나타나기를 기대합니다. 그것은 당신이하지 않는 tm_isdst 멤버에 값을 할당

#include <time.h> 
#include <stdio.h> 
int main(void) { 
    struct tm t = { 
     .tm_year = 4, 
     .tm_mon = 9, 
     .tm_mday = 30, 
     .tm_hour = 0, 
     .tm_min = 0, 
     .tm_sec = 0, 
     .tm_isdst = -1, /* let mktime() figure it out */ 
    }; 

    printf("%04d-%02d-%02d %02d:%02d:%02d\n", 
      1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); 
    // output: 1904-10-30 00:00:00 

    mktime(&t); 

    printf("%04d-%02d-%02d %02d:%02d:%02d\n", 
      1900+t.tm_year, 1+t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); 
    // output: 1904-10-29 23:36:42 
} 

:

http://www.timeanddate.com/time/change/hong-kong/hong-kong?year=1904

다음

좀 더 명확하게 문제를 보여줍니다 프로그램의 수정 된 버전입니다 ; 초기화되지 않은 값으로 예측할 수없는 동작이 발생할 수 있습니다. 또한 프로그램의 문자가 tm_mday 인 경우 tm_day으로 잘못 입력되었습니다.

:

$ ./c 
1904-10-30 00:00:00 
1904-10-30 00:00:00 
$ TZ=Asia/Hong_Kong ./c 
1904-10-30 00:00:00 
1904-10-29 23:36:42 
$ 

내가 할 수 있었다 방법에 대한 몇 가지 배경이 상당히 빨리 (다른 사람과 유사한 증상을보고 도움이 될 수 있음)이 알아낼 : 여기

내 시스템에서 출력의 질문은 강력하게 this one을 상기 시켰는데, 익숙한 것은 highest-scoring answerhighest-scoring user이고 스택 오버플로가 있기 때문입니다. 그것은 순수한 행운이었다.

처음으로 시간대를 알지 못했기 때문에 "1904 시간 변경"에 대한 Google의 검색 결과는 this page에서 비슷한시기가 룩셈부르크에서 같은 해를 변경하는 것으로 나타났습니다. 현대 표준 시간대로의 전환의 일환으로 전 세계 다른 지역에서도 비슷한시기에 비슷한 변화가 일어 났을 가능성이 있습니다.

Frxstrem 님의 의견에 따르면 "1904 Hong Kong time change"에 대한 Google 검색 결과는 this page입니다.

+2

사실 [1904 년 10 월 30 일 00:00:00] (http://www.timeanddate.com/time/change/hong-kong/hong-kong?year=1904) 홍콩의 시계가 돌아갔다. GMT보다 정확히 8 시간 앞당기려면 23 시간 24 초. – Frxstrem

+0

고마워 Keith와 Frxstrem, 너희들은 훌륭해! 네, 홍콩 시간대를 운영하고 있습니다. 그 답은 정확한 시프트 이유를 알려줍니다. 제안 된대로 UTC 시간대로 시도해보고 동작을 살펴 보겠습니다. 다시 한번 감사드립니다. – herbertng