0

I wrote the following piece of code to advance the input date to the following calendar date. This works well when tested in a dummy source file compiled with g++ 4.1.2

However, when running the following code from within my firm's simulator(intricate details of which are unavailable to me at this point), it breaks on 20021027; i.e. for dates other than 20021027, it works as intended but for 20021027, it returns 20021027 itself.

Please advise as to what could be going wrong?

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);
}
Mindstorm
  • 443
  • 1
  • 5
  • 12

2 Answers2

1

I don't see why that one date would cause problems, but I don't understand why you're doing things the hard way. Just add one to the tm_mday field before calling mktime, then extract the corrected values from the struct tm you passed into mktime. (There's a reason why the pointer into mktime points to non-const.) Something like:

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;
}

(You might want to add some sanity checks, i.e. verify that the int passed in really does represent a date in the expected format, and that n is in some reasonable range. Or if you can influence the decision, use some standard date format, so you don't have to.)

Anyway, I'd suspect some problem in the simulator, especially if it works with the same value locally.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Thank you for this piece of code. This does work and it turns out that it was the Daylight Savings Time that was causing the issue. Turns out DST ended in USA on 20021027! So, that would push the time back by one hour resulting in the code pointing back to the same date(since I was using the 00:00:00 reference). By setting tm_isdst=0(standard time) or using tm_hour=12, this problem gets resolved – Mindstorm Sep 06 '12 at 11:18
  • Shame on me for not recognizing it. I've done this often enough that I just automatically use noon, even without thinking about why. – James Kanze Sep 06 '12 at 11:28
0

you simply reached integer limit of 2147483647, wich is then rounded down.

Always check in your code if any number goes above that value^^. switching to unsigned should fix that (or well just remand the problem to 4294967295)

EDIT: you are correct. My answer is wrong.

Rax
  • 62
  • 4
  • 1
    In which expression does it overflow? I find that on a 32 bit machine he should be good to the year 214748. (There might be a problem with the value of `time_t`, but then he'd have major system problems as well. (A signed 32 bit `time_t`, starting at 1970, is good until 2038.) – James Kanze Sep 06 '12 at 10:18