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

"Andrés G. Aragoneses" knocte at gmail.com
Thu Nov 7 10:29:17 UTC 2013


Seconded.

On 07/11/13 11:16, Stifu wrote:
> 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