[Mono-dev] DateTime.Now gives a wrong time
Robert Jordan
robertj at gmx.net
Wed Oct 12 16:58:49 EDT 2011
On 12.10.2011 22:05, k0l0b0k.void at gmail.com wrote:
> Hello guys, thanks for your replies. I think, I've understand the situation.
> Some weeks ago, Ukraine and Belarus has timezone changes by law, and now we
> are FET timezone (GMT+3, without DST). As Robert pointed, I've look into
> TimeZone.* methods, and their native implementations, and found, that wrong
> GMT offset brings by glibc's mktime function. But, it is not mktime bug
> (however, I'm not sure), it is mono issue - code from icall.c:5931:
>
> memset (&start, 0, sizeof (start));
>
> start.tm_mday = 1;
> start.tm_year = year-1900;
>
> t = mktime (&start);
>
> I've found, that setting only tm_year in start struct is insufficiently. At
> least tm_mon must be set too, to avoid this issue. Simple test:
>
> #include<stdio.h>
> #include<time.h>
> #include<memory.h>
>
> int main(int argc, char *argv[])
> {
> struct tm t;
> memset(&t, 0, sizeof(t));
> t.tm_year = 111; // 2011
> t.tm_mon = 10; // wrong tm_gmtoff will received if comment out this line
tm_mon = 0 means January 1st 2011. Back then, the offset was GMT+2,
Eastern Europe Time, so the call is correct.
The problem is not tm_mon = 0, because Mono does it on purpose
to get the first day of the year:
https://github.com/mono/mono/blob/master/mono/metadata/icall.c#L6013
Then it starts looping to find out when the GMT offset is changing:
https://github.com/mono/mono/blob/master/mono/metadata/icall.c#L6038
This probably happened at some date in March:
https://github.com/mono/mono/blob/master/mono/metadata/icall.c#L6063
Then it loops further to find out when the GMT offset changes again.
But this second change is never happening, because FET remains
forever at GTM+3 => Mono thinks it's still on DST for the rest of
the year.
I believe the fix is to remove the if-statement at
https://github.com/mono/mono/blob/master/mono/metadata/icall.c#L6076
because the code inside the if-statement must be executed
regardless of is_daylight's value.
Robert
More information about the Mono-devel-list
mailing list