2012-09-06 38 views
0

我编写了以下代码片段以将输入日期提前到下一个日历日期。当在用g ++编译的虚拟源代码文件中测试时,此方法运行良好。4.1.2使用ctime提前指定日期到下一个日历日期的问题

但是,当从我公司的模拟器(其中错综复杂的细节在此处不可用)中运行以下代码时,它会在20021027 ;即20021027以外的日期,它按预期工作,但是对于20021027,它本身返回20021027。

请告知可能会出现什么问题?

int nextday(const int &date, int n=1) 
{ 
    struct tm curr_time; 

    int yyyy = curr_time.tm_year = date/10000-1900; 
    int mm = curr_time.tm_mon=(date/100)%100-1; 
    int dd = curr_time.tm_mday=date%100; 
    curr_time.tm_min=0; 
    curr_time.tm_sec=0; 
    curr_time.tm_hour=0; 

    time_t next = mktime(&curr_time) + 24*60*60*n; 
    struct tm new_time; 
    localtime_r(&next,&new_time); 
    yyyy = 1900 + new_time.tm_year; 
    mm = 1 + new_time.tm_mon; 
    dd = new_time.tm_mday; 
    return (10000*yyyy+100*mm+dd); 
} 

回答

1

我不明白为什么这一个日期会导致问题,但我不知道为什么你要做的事情困难的方式。在调用mktime之前,只需在 tm_mday字段中添加一个,然后从struct tm中提取已更正的 值,您将其传入mktime。 (还有一个原因 为什么指针变成mktime指向非const。)喜欢的东西:

int 
nextday(int date, int n = 1) 
{ 
    tm broken_down; 
    broken_down.tm_year = date/10000 - 1900; 
    broken_down.tm_mon = (date/100) % 100 - 1; 
    broken_down.tm_mday = date % 100 + n; 
    broken_down.tm_hour = 12; // avoid issues with summer time, etc. 
    broken_down.tm_min = 0; 
    broken_down.tm_sec = 0; 
    mktime(&broken_down); 
    return (broken_down.tm_year + 1900) * 10000 
     + (broken_down.tm_mon + 1) * 100 
     + broken_down.tm_mday; 
} 

(您可能要增加一些理智的检查,即验证,在真正通过int 并代表日期预期的格式,并且 n是在一些合理的范围内。或者,如果你能影响决策, 使用一些标准的日期格式,所以你不必。)

不管怎么说,我怀疑一些问题在模拟器中,特别是如果它在本地使用相同的值。

+0

谢谢你的这段代码。这确实有效,结果是夏令时导致了这个问题。 原来DST在美国结束20021027!因此,这会将时间推回一小时,导致代码指向相同的日期(因为我使用的是00:00:00引用) 通过设置tm_isdst = 0(标准时间)或使用tm_hour = 12,这个问题得到解决 – Mindstorm

+0

对我没有意识到这一点我感到羞耻,我经常这样做,我只是自动使用中午,即使没有考虑原因。 –

0

你只是达到2147483647的整数限制,然后向下舍入。

如果任何数字超过该值^^,请务必检查您的代码。切换到无符号应该修复(或只是将问题还原到4294967295)

编辑:你是正确的。我的回答是错误的。

+1

在哪个表达式中溢出?我发现在一台32位的机器上,他应该是214748年的好时机。(time_t的值可能有问题,但是他也会遇到重大的系统问题)(一个带符号的32位'time_t ',从1970年开始,直到2038年才有效。) –

相关问题