[Mono-dev] why does DateTime.Now.IsDaylightSavingTime() returns false when it should be true.

Stifu stifu at free.fr
Thu Nov 7 10:16:00 UTC 2013


I'm in no position to accept or review your patch, but I wanted to thank you
for taking the time and putting in the efforts needed to make Mono better
for everyone.

I hope this pull request gets attention soon.


Alistair Bush wrote
> Hi guys,
> 
> Please note that I have cleaned this up and bit and submitted a pull
> request
> 
> https://github.com/mono/mono/pull/800
> 
> Feedback welcome.
> 
> On Wed, Oct 30, 2013 at 11:51 PM, Alistair Bush <

> alistair.bush@

> > wrote:
>> Ok so firstly this is like the MOST C ive ever written in my life..
>> and it looks ugly and ive only vagely checked that it doesn't break
>> the northern hemisphere.
>>
>> But isn't this a better patch of the method?
>> (https://github.com/alistair/mono/commit/6912202aab5a424e98bc44d7b988c2791f9cccc1)
>>
>> Any help turning this into an acceptable pull request would be really
>> appreciated.
>>
>> diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c
>> index 618e4da..7f47624 100644
>> --- a/mono/metadata/icall.c
>> +++ b/mono/metadata/icall.c
>> @@ -5930,10 +5930,12 @@
>> ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year,
>> MonoArray
>>   struct tm start, tt;
>>   time_t t;
>>
>> - long int gmtoff;
>> - int is_daylight = 0, day;
>> + long int gmtoff, gmtoff_st, gmtoff_ds;
>> + int day, transitioned;
>>   char tzone [64];
>>
>> + gmtoff_st = gmtoff_ds = transitioned = 0;
>> +
>>   MONO_ARCH_SAVE_REGS;
>>
>>   MONO_CHECK_ARG_NULL (data);
>> @@ -5974,8 +5976,10 @@
>> ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year,
>> MonoArray
>>   t += 3600*24;
>>   tt = *localtime (&t);
>>
>> +        long int gmtoff_after = gmt_offset(&tt, t);
>> +
>>   /* Daylight saving starts or ends here. */
>> - if (gmt_offset (&tt, t) != gmtoff) {
>> + if (gmtoff_after != gmtoff) {
>>   struct tm tt1;
>>   time_t t1;
>>
>> @@ -5995,36 +5999,37 @@
>> ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year,
>> MonoArray
>>   strftime (tzone, sizeof (tzone), "%Z", &tt);
>>
>>   /* Write data, if we're already in daylight saving, we're done. */
>> - if (is_daylight) {
>> - mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
>> - mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) *
>> 10000000L);
>> - return 1;
>> + if (tt.tm_isdst) {
>> + mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
>> + mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) *
>> 10000000L);
>> + if (gmtoff_ds == 0) {
>> + gmtoff_st = gmtoff;
>> + gmtoff_ds = gmtoff_after;
>> + }
>> + transitioned++;
>>   } else {
>> - struct tm end;
>>   time_t te;
>> + te = mktime (&tt);
>>
>> - memset (&end, 0, sizeof (end));
>> - end.tm_year = year-1900 + 1;
>> - end.tm_mday = 1;
>> -
>> - te = mktime (&end);
>> -
>> - mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
>> - mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) *
>> 10000000L);
>>   mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
>>   mono_array_set ((*data), gint64, 1, ((gint64)te + EPOCH_ADJUST) *
>> 10000000L);
>> - is_daylight = 1;
>> + if (gmtoff_ds == 0) {
>> + gmtoff_st = gmtoff_after;
>> + gmtoff_ds = gmtoff;
>> + }
>> + transitioned++;
>>   }
>>
>>   /* This is only set once when we enter daylight saving. */
>> - mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
>> - mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) -
>> gmtoff) * 10000000L);
>> -
>> + if (tt1.tm_isdst) {
>> + mono_array_set ((*data), gint64, 2, (gint64)gmtoff_st * 10000000L);
>> + mono_array_set ((*data), gint64, 3, (gint64)(gmtoff_ds - gmtoff_st)
>> * 10000000L);
>> + }
>>   gmtoff = gmt_offset (&tt, t);
>>   }
>>   }
>>
>> - if (!is_daylight) {
>> + if (transitioned < 2) {
>>   strftime (tzone, sizeof (tzone), "%Z", &tt);
>>   mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
>>   mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
>>
>> On Tue, Oct 29, 2013 at 9:13 AM, Alistair Bush <

> alistair.bush@

> > wrote:
>>> Well that certainly sucks.
>>>
>>>
>>> On Tue, Oct 29, 2013 at 3:03 AM, Robert Jordan <

> robertj@

> > wrote:
>>>>
>>>> On 28.10.2013 07:35, Alistair Bush wrote:
>>>>>
>>>>> I am trying to figure out why exactly running
>>>>> DateTime.Now.IsDaylightSavingTIme() returns false.
>>>>> I live in the Auckland/Pacific timezone and pretty much everywhere I
>>>>> look it confirms that yes it is daylight saving time.
>>>>
>>>>
>>>> Unfortunately, I don't remember the details, but I'm pretty
>>>> sure that ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData
>>>> has a bug w/ respect to the Southern Hemisphere.
>>>>
>>>> The code assumes that a year always begins outside a DST zone,
>>>> and this is obviously incorrect for the Southern Hemisphere.
>>>>
>>>> To fix this, the local var "is_daylight" must be properly
>>>> initialized. Currently, it's always 0 at start, but it must
>>>> be initialized with 1 when January, 1st is inside a DST
>>>> zone.
>>>>
>>>> Maybe this:
>>>>
>>>>         is_daylight = start.tm_isdst > 0;
>>>>
>>>> just before
>>>>
>>>>         /* For each day of the year, calculate the tm_gmtoff. */
>>>>         for (day = 0; day < 365; day++) {
>>>>
>>>> Robert
>>>>
>>>>
>>>> _______________________________________________
>>>> Mono-devel-list mailing list
>>>> 

> Mono-devel-list at .ximian

>>>> http://lists.ximian.com/mailman/listinfo/mono-devel-list
>>>
>>>
> _______________________________________________
> Mono-devel-list mailing list

> Mono-devel-list at .ximian

> http://lists.ximian.com/mailman/listinfo/mono-devel-list





--
View this message in context: http://mono.1490590.n4.nabble.com/why-does-DateTime-Now-IsDaylightSavingTime-returns-false-when-it-should-be-true-tp4661190p4661263.html
Sent from the Mono - Dev mailing list archive at Nabble.com.


More information about the Mono-devel-list mailing list