SymbiSoft / mosync

Automatically exported from code.google.com/p/mosync
0 stars 0 forks source link

split_time wrong for year 2000 and earlier #1038

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?

Run this C++ code as new MoSync-project:

#include <ma.h>
#include <matime.h>
#include <conprint.h>

    void testtime() {
        tm t;
        t.tm_hour = 10;
        t.tm_mon = 0;
        t.tm_mday = 10;
        t.tm_sec = 0;
        t.tm_year = 100;
        t.tm_wday = 0;
        t.tm_min = 20;
        t.tm_yday = 0;

        int secsSince1970 = mktime(&t);
        printf("secsSince1970=%i", secsSince1970);

        tm t2;
        split_time(secsSince1970, &t2);
        printf("year=%i month=%i day=%i", t2.tm_year, t2.tm_mon, t2.tm_mday);
        int s2 = mktime(&t2);
        printf("secsSince1970=%i", s2);

        tm t3;
        split_time(s2, &t3);
        printf("year=%i month=%i day=%i", t3.tm_year, t3.tm_mon, t3.tm_mday);
        int s3 = mktime(&t3);
        printf("secsSince1970=%i", s3);

    }

extern "C" int MAMain() {
    testtime();
    return 0;
}

What is the expected output? What do you see instead?

The date is 10th January 2000.
I expect the newly created tm-struct to stay the same after having run "mktime" 
followed by split_time.

Instead the date becomes one day less.
9th january on first cycle, 8th on next etc.

What version of the product are you using? On what operating system?

2.4.0-r2425 on Mac OS X Snow Leopard

Please provide any additional information below.

For dates 2001 and up, the result is correct.

Seems to be related to issue 495.

If code for split_time matime.c is reverted to version before that fix, I get 
the correct date for year 2000 and down, but wrong for dates 2001 and up.

Original issue reported on code.google.com by mayhem...@hotmail.no on 5 Feb 2011 at 6:41

GoogleCodeExporter commented 8 years ago

This algorithm from minix source seems to work fine:

http://www.raspberryginger.com/jbailey/minix/html/gmtime_8c-source.html

Original comment by mayhem...@hotmail.no on 5 Feb 2011 at 9:37

GoogleCodeExporter commented 8 years ago
Sorry for referring to that Minix-algorithm. Forget that. It doesn't work at 
all for dates before 1970. (1969 becomes 2105) :-|

Original comment by mayhem...@hotmail.no on 5 Feb 2011 at 10:31

GoogleCodeExporter commented 8 years ago
Proposed fix also added as comment on issue 495 :

The problem seems not to have been "+1" on line #113: "res->tm_mday = days + 
1;",
but the use of the _ISLEAP(y) macro on lines #91 and #103.

"y" on these lines are the full years (i.e: 1999,2000,2001 etc), while the 
macro is converted to expect y-1900 (i.e: 99,100,101)

_ISLEAP(2000) returns 0
_ISLEAP(100) returns 1

So that 2000 is concidered NOT to be a leap-year, while it actually is.
Therefore in the original code all split_time()-calls for dates after 
29.Feb.2000 gets wrong, while in the current code (with no +1), all dates 
before 1.March 2000 gets wrong instead.

I think the fix should be:

line #91:    yleap = _ISLEAP(y-1900);
line #103:   yleap = _ISLEAP(y-1900);
line #113:   res->tm_mday = days + 1;    // as originally

(Don't change the _ISLEAP-macro, because it is also used by _DAYS_IN_YEAR(year) 
macro, but then with "short-years" (i.e: 99,100,101))

Original comment by royandre...@gmail.com on 17 Nov 2011 at 8:49