2012-09-03 44 views
1

我有一個mktime問題,如果小時因爲DST更改而不存在,那麼使用MSVS 2010的窗口上的mktime將返回一個time_t在我的情況下爲23:00,當它應該在第二天上午1:00返回時(在Linux上它將返回上午1:00,因爲它應該)。我的問題正好發生在巴西時區(格林威治標準時間-3),恰好在自動調整夏令時的時候。在他們的情況下,這發生在2012年12月21日凌晨0點(這將變成凌晨1點)。轉換不存在的struct tm時mktime問題(由於日光轉換時間)

這是代碼的一部分:

/* test_date1.cpp : Defines the entry point for the console application. 
* 
*/ 
#include "StdAfx.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <time.h> 

int _tmain(int argc, _TCHAR* argv[]) 
{ 

time_t mytime=1350784881; 
struct tm *timeinfo; 
char *tz; 

/*time (&mytime); */ 
timeinfo = localtime (&mytime); 

printf("%.2d/%.2d/%.4d, %.2d:%.2d isdst?=%d\n", 
timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year, timeinfo->tm_hour, timeinfo-> tm_min, timeinfo -> tm_isdst); 

timeinfo->tm_mday=21; 
timeinfo->tm_mon=9; 
timeinfo->tm_year=112; 
timeinfo->tm_hour=0; 
timeinfo->tm_min=0; 
timeinfo->tm_isdst=-1; 

printf("The shit: %.2d/%.2d/%.4d, %.2d:%.2d isdst?=%d\n", 
    timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year, timeinfo->tm_hour, timeinfo-> tm_min, timeinfo -> tm_isdst); 

mytime= mktime(timeinfo); 
printf("mytime is=%d\n", mytime); 

timeinfo = localtime (&mytime); 

printf("%.2d/%.2d/%.4d, %.2d:%.2d isdst?=%d\n", 
    timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year, timeinfo->tm_hour, timeinfo-> tm_min, timeinfo -> tm_isdst); 

return 0; 
} 

在Windows上的結果是:

20/09/0112, 23:01 isdst?=0 
21/09/0112, 00:00 isdst?=-1 
mytime is=1350784800 
20/09/0112, 23:00 isdst?=0 

在Linux是:

20/09/0112, 23:01 isdst?=0 
21/09/0112, 00:00 isdst?=-1 
mytime is=1350788400 
21/09/0112, 01:00 isdst?=1 

正如你所看到的數值指明MyTime差異在time_t從Unix返回C和從Microsoft Visual Studio 2010返回C之間是3600秒。

這個程序應該運行在不同的平臺上(UNIX/WINDOWS/etc)和任何時區,所以我不應該對時區進行硬編碼。

正如你看到的問題是在Windows上錯誤地返回時間。在這一刻,我不知道如何解決這個問題。有人有這個特殊問題嗎?你是如何解決它的?我特別需要當地的日子。

非常感謝,

Jokerush

+0

當你問這樣的問題時,總是記錄操作系統版本。看看TZ環境變量帶給你什麼。 –

回答

0

我不知道,當你傳遞一個無效的時間mktime的行爲定義,所以這可能不是實際上是一個錯誤。

無論如何,您自己不需要重新實施mktime,您需要解決該問題。我提出以下算法:

  • 在當天的上午9點建立一個struct tm。
  • 轉換爲time_t。
  • 從time_t減去24小時。

如果夏令時沒有變化,那麼此時您正在查看前一天的上午9點。如果夏令時開始,你正在看早上8點;如果它完成了,你在上午10點看。

  • 轉換回結構tm。
  • 將struct tm中的日期與原始日期進行比較。
  • 如果還不是正確的一天,請在time_t上添加一小時並重試。

由於您一次只能添加一小時,所以一旦您獲得了想要的日期,就可以確定您已經獲得了該日期的最早時間。

我正在做一些我認爲目前安全的假設:夏令時從未開始或完成半小時,從未在早上8點到上午10點之間開始或結束,而且從未更改過比一個小時。

我故意不假設夏令從來沒有開始或結束在晚上(例如,晚上11點午夜變成或反之亦然),或在清晨(例如,凌晨2點變爲凌晨3點,反之亦然,這正如它發生的恰恰是這裏發生的事情)。