2012-08-25 3 views
9

코드 아래에서 실행 중입니다. 위의 프로그램을 실행하면mktime() 함수의 혼동스러운 행동 : 하나씩 tm_hour 수를 늘림

int main() 
{ 
struct tm storage={0,0,0,0,0,0,0,0,0}; 
char *p = NULL; 
p = (char *)strptime("2012-08-25 12:23:12","%Y-%m-%d %H:%M:%S",&storage); 
char buff[1024]={0}; 
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage); 
cout << buff << endl; 
storage.tm_sec += 20; 
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage); 
cout << buff << endl; 
mktime(&storage); 
strftime(buff,1024,"%Y-%m-%d %H:%M:%S",&storage); 
cout << buff << endl; 
return 0; 
} 

는 대신 '2012-08-25 12시 23분 32초'의 '2012-08-25 13시 23분 32초'인쇄합니다. 제발, 왜 그것이 tm_hour 가치가 증가 도움이됩니다. 프로그램에 입력 날짜를 '2012-02-25 12:23:32'로 입력하면 제대로 작동합니다.

출력 - 내 시스템>

[[email protected] root]$ ./a.out 
2012-08-25 12:23:12 
2012-08-25 12:23:32 
2012-08-25 13:23:32 
[[email protected] root]$ 

날짜 정보는 ->

[[email protected] root]$ date 
Sat Aug 25 08:28:26 EDT 2012 
+0

코드에 시간이 증가하는 것으로 표시되지 않습니다.그렇게하기 위해서는'strptime'에서 나온 결과와'mktime'에 대한 호출 결과를 출력하십시오. 그러면 실제로 일어나는 일을 막을 수 있습니다. –

+0

죄송합니다. 구문 분석 할 수 없습니다. 그것은 하나가 아닌 세 개의 산출물을 가지고 있지만 어디에서 왔는지를 알려주지 않습니다. 출력과 일치하도록 샘플 코드를 업데이트하십시오. –

답변

11

지정한 날짜가 유효 일광 절약이 있지만 mktime를 호출 할 때, storage.tm_isdst가 제로

어떻게됩니까. mktime이 이것을보고 "어이, 그들은 나에게 일광 절약 플래그가 잘못된 날짜를주었습니다. 고칠 수 있습니다."라고 생각합니다. 그런 다음 tm_isdst을 1로 설정하고 tm_hour을 변경합니다.

도 참조하십시오. this 답.

setenv("TZ", "", 1); 
tzset(); 
mktime();
  • 좋은 날짜 -를 사용

    • 사용 timegm 대신 (timegm에서도 예 참조) mktime를 호출하기 전에 UTC로 시간대를 설정 mktime
    • 의 해결하려면 시간 라이브러리 (예 : boost::locale::date_time/boost::date_time,하지만 Q & A 섹션 읽기 boost::locale::date_time 페이지에서 하나를 선택하기 전)
  • +1

    고마워요, 그것은 내 의심을 도왔습니다. 이제 두 가지 유형의 시스템 (DST 사용 및 사용 안함)에서 코드 조각을 실행해야합니다. 예 : mktime()을 호출하기 전에 tm_isdst = 1을 코드에 넣으면 DST가 꺼진 시스템에서 잘못된 결과가 나타납니다 (tm_hour가 1 씩 감소합니다). 주어진 날짜에 초를 더하는 다른 방법이 있습니까? ("mktime() 사용 금지"또는 "tm_isdst 플래그를 무시하는 mktime() 사용") –

    +0

    @DhirajNeve : 몇 가지 수정 사항을 추가했습니다. 더 많은 날짜/시간 관련 일을해야한다면 좋은 C++ 날짜/시간 라이브러리를 사용해야한다고 생각합니다. – rve

    +0

    'timegm' POSIX만이 아닌가요? – stackptr

    4

    와우, 그냥 주위에 방법이 없습니다. 시스템의 mktime (3) 구현 버그입니다. mktime (3)은 struct tm *을 넘겨서는 안됩니다.

    storage.tm_isdst의 값을 확인하는 것이 좋습니다. DST에 대해 혼란스럽지 않게하려면 0으로 설정하십시오. 그래도 작동하지 않으면 -1로 설정하여 자동으로 적절한 값을 결정하십시오.

    mktime - convert broken-down time into time since the Epoch

    한다 mktime()가 일광 절약 시간은, 각각, 또는 지정된 시간을위한 효과가 아닌지 초기 추정되게 tm_isdst에게 긍정적 또는 0 값

    . tm_isdst가 음수이면 mktime()이 일광 절약 시간이 지정된 시간 동안 유효한지 여부를 확인하려고 시도합니다.

    나는에서는 mktime (3) struct tm *을 수정하지 잘못이었다. 값을 정규화하는 것은 올바른 동작입니다.

    +0

    'man mktime' (http://linux.die.net/man/3/mktime)에 따르면'stuct tm'을 변경할 수 있습니다. 값을 정규화하고 누락 된 필드를 채 웁니다. – rve

    +0

    @rve 당신이 옳은 것처럼 보입니다. 나는 그 말씨를 오해했다. 나는 time_t를 설정하는 목적으로 정상화하고 있다고 생각했다. –

    +0

    네, 구현이 잘못되었습니다 ... –

    관련 문제