Let's get this patch in and fix any possible issue later. Thanks!

Atsushi Eno

(2013年11月07日 18:07), 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.b...@gmail.com> 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.b...@gmail.com> wrote:
Well that certainly sucks.


On Tue, Oct 29, 2013 at 3:03 AM, Robert Jordan <robe...@gmx.net> 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@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list

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




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

Reply via email to