Windows 转换不存在的struct tm时的mktime问题(由于日光变化时间)

Windows 转换不存在的struct tm时的mktime问题(由于日光变化时间),windows,dst,mktime,Windows,Dst,Mktime,我有一个mktime问题,如果由于DST更改,小时不存在,那么使用MSVS 2010的windows上的mktime将返回过去的时间,在我的例子中是23:00,当它在Linux上第二天返回1:00AM时,它将返回1:00AM。我的问题发生在巴西时区GMT-3上,自动调整夏令时的确切时间。在他们的情况下,这种情况发生在2012年10月21日凌晨0:00,将变为凌晨1:00 这是代码的一部分: /* test_date1.cpp : Defines the entry point for the c

我有一个mktime问题,如果由于DST更改,小时不存在,那么使用MSVS 2010的windows上的mktime将返回过去的时间,在我的例子中是23:00,当它在Linux上第二天返回1:00AM时,它将返回1:00AM。我的问题发生在巴西时区GMT-3上,自动调整夏令时的确切时间。在他们的情况下,这种情况发生在2012年10月21日凌晨0:00,将变为凌晨1:00

这是代码的一部分:

/* 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;
}
在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是从Unix返回C的时间与从Microsoft Visual Studio 2010返回C的时间之间的3600秒

这个程序应该在不同的平台UNIX/WINDOWS/etc和任何时区上运行,所以我不应该硬编码时区

正如您所看到的,问题出现在错误返回时间的Windows上。在这一刻,我不知道如何解决这个问题。有人有这个问题吗?你是怎么解决的?我特别需要当地一天的开始

非常感谢


Jokerush

我不知道当您传递一个无效时间时是否定义了mktime的行为,因此这实际上可能不是一个bug

无论如何,除非您自己重新实现mktime,否则您需要解决这个问题。我提出以下算法:

在当天上午9点建立struct tm。 转换为时间。 从时间中减去24小时。 如果没有夏时制的改变,那么现在你看到的是前一天早上9点。如果夏令时开始了,你现在看到的是早上8点;如果它完成了,你将看到上午10点

转换回struct tm。 将struct tm中的日期与原始日期进行比较。 如果今天不是合适的日子,请在时间上再加一小时,然后再试一次。 因为你一次只增加一个小时,一旦你得到了你想要的日期,你可以确定你得到了该日期的最早时间

我做了一些我认为目前是安全的假设:夏令时从不在一小时内开始或结束,从不在上午8点到10点之间开始或结束,也从不超过一小时


我无意假设夏令时从不在晚上开始或结束,例如晚上11点变为午夜,反之亦然,或者在清晨,例如凌晨2点变为凌晨3点,反之亦然,这正是这里发生的事情。

当你问这样的问题时,一定要记录操作系统的版本。看看TZ环境变量给你带来了什么。
20/09/0112, 23:01 isdst?=0
21/09/0112, 00:00 isdst?=-1
mytime is=1350788400
21/09/0112, 01:00 isdst?=1