我有一个mktime问题,如果由于DST更改而不存在小时,则使用MSVS 2010的Windows上的mktime将返回过去的time_t,在我的情况下为23:00,当它应该返回1:00 AM第二天(在Linux上,它应该在凌晨1点返回)。我的问题恰好发生在巴西时区(格林威治标准时间-3),恰好是自动调整夏令时的时间。在他们的情况下,这发生在2012年8月21日凌晨0点(这将是凌晨1点)。
这是代码的一部分:
/* 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 diff在time_t从Unix返回C和从Microsoft Visual Studio 2010返回C之间的时间是3600秒。
这个程序应该在不同的平台(UNIX / WINDOWS / etc)和任何时区运行,所以我不应该对时区进行硬编码。
正如您所看到的那样,问题是在Windows上错误地返回时间。在这一刻我不知道如何解决这个问题。有人有这个特殊问题吗?你是怎么解决的?我特别需要瞄准当地日。
非常感谢,
Jokerush
答案 0 :(得分:0)
我不知道当你传递一个无效的时间时是否定义了mktime的行为,所以这实际上可能不是一个bug。
无论如何,如果没有自己重新实施mktime,你需要解决这个问题。我提出以下算法:
如果没有夏令时变化,那么此时您正在查看前一天上午9点。如果开始夏令时,你会看到早上8点;如果它完成了,你看的是上午10点。
由于你一次只增加一个小时,一旦你得到你想要的日期,你可以确定你在那个日期有最早的时间。
我做了一些我认为目前安全的假设:夏令时永远不会开始或在一小时内完成,它永远不会在早上8点到早上10点之间开始或结束,并且永远不会超过一小时。
我故意不假设夏令时从未开始或在晚上结束(例如,晚上11点变为午夜或反之亦然)或在清晨(例如,凌晨2点变为凌晨3点或副-versa,碰巧就是这里发生的事情)。