merge
authorDão Gottwald <dao@mozilla.com>
Sun, 28 Jun 2009 12:52:40 +0200
changeset 29786 29b767814d87
parent 29784 ca23d3b5a999 (current diff)
parent 29785 4548b8be232f (diff)
child 29787 96450c57dd02
push id106
push userhsivonen@iki.fi
push dateSun, 28 Jun 2009 17:44:42 +0000
milestone1.9.2a1pre
merge
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -371,16 +371,19 @@ EquivalentYearForDST(jsint year)
     if (day < 0)
         day += 7;
 
     isLeapYear = (DaysInYear(year) == 366);
 
     return yearStartingWith[isLeapYear][day];
 }
 
+/* LocalTZA gets set by js_InitDateClass() */
+static jsdouble LocalTZA;
+
 static jsdouble
 DaylightSavingTA(jsdouble t)
 {
     volatile int64 PR_t;
     int64 ms2us;
     int64 offset;
     jsdouble result;
 
@@ -408,16 +411,32 @@ DaylightSavingTA(jsdouble t)
 
     offset = PRMJ_DSTOffset(PR_t);
 
     JSLL_DIV(offset, offset, ms2us);
     JSLL_L2D(result, offset);
     return result;
 }
 
+static jsdouble
+AdjustTime(jsdouble date)
+{
+    jsdouble t = DaylightSavingTA(date) + LocalTZA;
+    t = (LocalTZA >= 0) ? fmod(t, msPerDay) : -fmod(msPerDay - t, msPerDay);
+    return t;
+}
+
+#define LocalTime(t)    ((t) + AdjustTime(t))
+
+static jsdouble
+UTC(jsdouble t)
+{
+    return t - AdjustTime(t - LocalTZA);
+}
+
 static intN
 HourFromTime(jsdouble t)
 {
     intN result = (intN) fmod(floor(t/msPerHour), HoursPerDay);
     if (result < 0)
         result += (intN)HoursPerDay;
     return result;
 }
@@ -462,19 +481,18 @@ msFromTime(jsdouble t)
  */
 
 /*
  * We use the first reseved slot to store UTC time, and the second for caching
  * the local time. The initial value of the cache entry is NaN.
  */
 const uint32 JSSLOT_UTC_TIME    = JSSLOT_PRIVATE;
 const uint32 JSSLOT_LOCAL_TIME  = JSSLOT_PRIVATE + 1;
-const uint32 JSSLOT_LOCAL_TZA   = JSSLOT_PRIVATE + 2;
 
-const uint32 DATE_RESERVED_SLOTS = 3;
+const uint32 DATE_RESERVED_SLOTS = 2;
 
 JSClass js_DateClass = {
     js_Date_str,
     JSCLASS_HAS_RESERVED_SLOTS(DATE_RESERVED_SLOTS) |
     JSCLASS_HAS_CACHED_PROTO(JSProto_Date),
     JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,  JS_PropertyStub,
     JS_EnumerateStub, JS_ResolveStub,   JS_ConvertStub,   JS_FinalizeStub,
     JSCLASS_NO_OPTIONAL_MEMBERS
@@ -501,100 +519,16 @@ static int ttb[] = {
     2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
     10000 + 0, 10000 + 0, 10000 + 0,   /* GMT/UT/UTC */
     10000 + 5 * 60, 10000 + 4 * 60,    /* EST/EDT */
     10000 + 6 * 60, 10000 + 5 * 60,    /* CST/CDT */
     10000 + 7 * 60, 10000 + 6 * 60,    /* MST/MDT */
     10000 + 8 * 60, 10000 + 7 * 60     /* PST/PDT */
 };
 
-static jsdouble
-LocalTZA()
-{
-    return -(PRMJ_LocalGMTDifference() * msPerSecond);
-}
-
-static JSBool
-GetAndCacheLocalTZA(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
-{
-    jsval v;
-    jsdouble result;
-    jsdouble *cached;
-
-    v = obj->fslots[JSSLOT_LOCAL_TZA];
-
-    result = *JSVAL_TO_DOUBLE(v);
-
-    if (JSDOUBLE_IS_NaN(result)) {
-        result = LocalTZA();
-
-        cached = js_NewWeaklyRootedDouble(cx, result);
-        if (!cached)
-            return JS_FALSE;
-
-        obj->fslots[JSSLOT_LOCAL_TZA] = DOUBLE_TO_JSVAL(cached);
-    }
-
-    *dp = result;
-    return JS_TRUE;
-}
-
-static jsdouble
-AdjustTime(jsdouble date, jsdouble localTZA)
-{
-    jsdouble t = DaylightSavingTA(date) + localTZA;
-    t = (localTZA >= 0) ? fmod(t, msPerDay) : -fmod(msPerDay - t, msPerDay);
-    return t;
-}
-
-static JSBool
-GetAdjustTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble t, jsdouble *dp)
-{
-    if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
-        return JS_FALSE;
-
-    jsdouble localTZA;
-    if (!GetAndCacheLocalTZA(cx, obj, vp, &localTZA))
-        return JS_FALSE;
-
-    *dp = AdjustTime(t, localTZA);
-
-    return JS_TRUE;
-}
-
-static JSBool
-ConvertToUTC(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
-{
-    if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
-        return JS_FALSE;
-
-    jsdouble localTZA;
-    if (!GetAndCacheLocalTZA(cx, obj, vp, &localTZA))
-        return JS_FALSE;
-
-    *dp = *dp - AdjustTime(*dp - localTZA, localTZA);
-
-    return JS_TRUE;
-}
-
-static JSBool
-ConvertToLocalTime(JSContext *cx, JSObject *obj, jsval *vp, jsdouble *dp)
-{
-    if (!obj || !JS_InstanceOf(cx, obj, &js_DateClass, vp ? vp + 2 : NULL))
-        return JS_FALSE;
-
-    jsdouble localTZA;
-    if (!GetAndCacheLocalTZA(cx, obj, vp, &localTZA))
-        return JS_FALSE;
-
-    *dp = *dp + AdjustTime(*dp, localTZA);
-
-    return JS_TRUE;
-}
-
 /* helper for date_parse */
 static JSBool
 date_regionMatches(const char* s1, int s1off, const jschar* s2, int s2off,
                    int count, int ignoreCase)
 {
     JSBool result = JS_FALSE;
     /* return true if matches, otherwise, false */
 
@@ -688,17 +622,17 @@ date_UTC(JSContext *cx, uintN argc, jsva
         return JS_FALSE;
 
     msec_time = TIMECLIP(msec_time);
 
     return js_NewNumberInRootedValue(cx, msec_time, vp);
 }
 
 static JSBool
-date_parseString(JSContext *cx, JSObject *obj, JSString *str, jsdouble *result)
+date_parseString(JSString *str, jsdouble *result)
 {
     jsdouble msec;
 
     const jschar *s;
     size_t limit;
     size_t i = 0;
     int year = -1;
     int mon = -1;
@@ -938,23 +872,20 @@ date_parseString(JSContext *cx, JSObject
     mon -= 1; /* convert month to 0-based */
     if (sec < 0)
         sec = 0;
     if (min < 0)
         min = 0;
     if (hour < 0)
         hour = 0;
     if (tzoffset == -1) { /* no time zone specified, have to use local */
-        *result = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
-        if (obj) {
-            return ConvertToUTC(cx, obj, NULL, result);
-        }
+        jsdouble msec_time;
+        msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
 
-        jsdouble localTZA = LocalTZA();
-        *result = *result - AdjustTime(*result - localTZA, localTZA);
+        *result = UTC(msec_time);
         return JS_TRUE;
     }
 
     msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
     msec += tzoffset * msPerMinute;
     *result = msec;
     return JS_TRUE;
 
@@ -973,17 +904,17 @@ date_parse(JSContext *cx, uintN argc, js
     if (argc == 0) {
         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
         return JS_TRUE;
     }
     str = js_ValueToString(cx, vp[2]);
     if (!str)
         return JS_FALSE;
     vp[2] = STRING_TO_JSVAL(str);
-    if (!date_parseString(cx, NULL, str, &result)) {
+    if (!date_parseString(str, &result)) {
         *vp = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
         return JS_TRUE;
     }
 
     result = TIMECLIP(result);
     return js_NewNumberInRootedValue(cx, result, vp);
 }
 
@@ -1069,18 +1000,17 @@ GetAndCacheLocalTime(JSContext *cx, JSOb
     result = *JSVAL_TO_DOUBLE(v);
 
     if (JSDOUBLE_IS_NaN(result)) {
         if (!GetUTCTime(cx, obj, vp, &result))
             return JS_FALSE;
 
         /* if result is NaN, it couldn't be finite. */
         if (JSDOUBLE_IS_FINITE(result))
-            if (!ConvertToLocalTime(cx, obj, vp, &result))
-                return JS_FALSE;
+            result = LocalTime(result);
 
         cached = js_NewWeaklyRootedDouble(cx, result);
         if (!cached)
             return JS_FALSE;
 
         obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cached);
     }
 
@@ -1410,19 +1340,20 @@ date_makeTime(JSContext *cx, uintN maxar
         args[i] = js_ValueToNumber(cx, &argv[i]);
         if (JSVAL_IS_NULL(argv[i]))
             return JS_FALSE;
         if (!JSDOUBLE_IS_FINITE(args[i]))
             return SetDateToNaN(cx, vp);
         args[i] = js_DoubleToInteger(args[i]);
     }
 
-    lorutime = result;
-    if (local && !ConvertToLocalTime(cx, obj, vp, &lorutime))
-        return JS_FALSE;
+    if (local)
+        lorutime = LocalTime(result);
+    else
+        lorutime = result;
 
     argp = args;
     stop = argp + argc;
     if (maxargs >= 4 && argp < stop)
         hour = *argp++;
     else
         hour = HourFromTime(lorutime);
 
@@ -1439,18 +1370,22 @@ date_makeTime(JSContext *cx, uintN maxar
     if (maxargs >= 1 && argp < stop)
         msec = *argp;
     else
         msec = msFromTime(lorutime);
 
     msec_time = MakeTime(hour, min, sec, msec);
     result = MakeDate(Day(lorutime), msec_time);
 
-    if (local && !ConvertToUTC(cx, obj, vp, &result))
-        return JS_FALSE;
+/*     fprintf(stderr, "%f\n", result); */
+
+    if (local)
+        result = UTC(result);
+
+/*     fprintf(stderr, "%f\n", result); */
 
     result = TIMECLIP(result);
     if (!SetUTCTime(cx, obj, NULL, result))
         return JS_FALSE;
 
     return js_NewNumberInRootedValue(cx, result, vp);
 }
 
@@ -1536,20 +1471,17 @@ date_makeDate(JSContext *cx, uintN maxar
 
     /* return NaN if date is NaN and we're not setting the year,
      * If we are, use 0 as the time. */
     if (!(JSDOUBLE_IS_FINITE(result))) {
         if (maxargs < 3)
             return js_NewNumberInRootedValue(cx, result, vp);
         lorutime = +0.;
     } else {
-        lorutime = result;
-
-        if (local && ConvertToLocalTime(cx, obj, vp, &lorutime))
-            return JS_FALSE;
+        lorutime = local ? LocalTime(result) : result;
     }
 
     argp = args;
     stop = argp + argc;
     if (maxargs >= 3 && argp < stop)
         year = *argp++;
     else
         year = YearFromTime(lorutime);
@@ -1562,18 +1494,18 @@ date_makeDate(JSContext *cx, uintN maxar
     if (maxargs >= 1 && argp < stop)
         day = *argp++;
     else
         day = DateFromTime(lorutime);
 
     day = MakeDay(year, month, day); /* day within year */
     result = MakeDate(day, TimeWithinDay(lorutime));
 
-    if (local && !ConvertToUTC(cx, obj, vp, &result))
-        return JS_FALSE;
+    if (local)
+        result = UTC(result);
 
     result = TIMECLIP(result);
     if (!SetUTCTime(cx, obj, NULL, result))
         return JS_FALSE;
 
     return js_NewNumberInRootedValue(cx, result, vp);
 }
 
@@ -1634,30 +1566,25 @@ date_setYear(JSContext *cx, uintN argc, 
     if (!JSDOUBLE_IS_FINITE(year))
         return SetDateToNaN(cx, vp);
 
     year = js_DoubleToInteger(year);
 
     if (!JSDOUBLE_IS_FINITE(result)) {
         t = +0.0;
     } else {
-        t = result;
-
-        if (!ConvertToLocalTime(cx, obj, vp, &t))
-            return JS_FALSE;
+        t = LocalTime(result);
     }
 
     if (year >= 0 && year <= 99)
         year += 1900;
 
     day = MakeDay(year, MonthFromTime(t), DateFromTime(t));
     result = MakeDate(day, TimeWithinDay(t));
-
-    if (!ConvertToUTC(cx, obj, vp, &result))
-        return JS_FALSE;
+    result = UTC(result);
 
     result = TIMECLIP(result);
     if (!SetUTCTime(cx, obj, NULL, result))
         return JS_FALSE;
 
     return js_NewNumberInRootedValue(cx, result, vp);
 }
 
@@ -1759,46 +1686,33 @@ new_explode(jsdouble timeval, PRMJTime *
 }
 
 typedef enum formatspec {
     FORMATSPEC_FULL, FORMATSPEC_DATE, FORMATSPEC_TIME
 } formatspec;
 
 /* helper function */
 static JSBool
-date_format(JSContext *cx, JSObject *obj, jsdouble date, formatspec format, jsval *rval)
+date_format(JSContext *cx, jsdouble date, formatspec format, jsval *rval)
 {
     char buf[100];
     JSString *str;
     char tzbuf[100];
     JSBool usetz;
     size_t i, tzlen;
     PRMJTime split;
 
     if (!JSDOUBLE_IS_FINITE(date)) {
         JS_snprintf(buf, sizeof buf, js_NaN_date_str);
     } else {
-        jsdouble local;
-        jsdouble adjustTime;
-
-        if (obj) {
-            local = date;
-            if (!ConvertToLocalTime(cx, obj, NULL, &local))
-                return JS_FALSE;
-
-            if (!GetAdjustTime(cx, obj, NULL, date, &adjustTime))
-                return JS_FALSE;
-        } else {
-            adjustTime = AdjustTime(date, LocalTZA());
-            local = date + adjustTime;
-        }
+        jsdouble local = LocalTime(date);
 
         /* offset from GMT in minutes.  The offset includes daylight savings,
            if it applies. */
-        jsint minutes = (jsint) floor(adjustTime / msPerMinute);
+        jsint minutes = (jsint) floor(AdjustTime(date) / msPerMinute);
 
         /* map 510 minutes to 0830 hours */
         intN offset = (minutes / 60) * 100 + minutes % 60;
 
         /* print as "Wed Nov 05 19:38:03 GMT-0800 (PST) 1997" The TZA is
          * printed as 'GMT-0800' rather than as 'PST' to avoid
          * operating-system dependence on strftime (which
          * PRMJ_FormatTimeUSEnglish calls, for %Z only.)  win32 prints
@@ -1901,29 +1815,25 @@ date_toLocaleHelper(JSContext *cx, const
     obj = JS_THIS_OBJECT(cx, vp);
     if (!GetUTCTime(cx, obj, vp, &utctime))
         return JS_FALSE;
 
     if (!JSDOUBLE_IS_FINITE(utctime)) {
         JS_snprintf(buf, sizeof buf, js_NaN_date_str);
     } else {
         intN result_len;
-
-        jsdouble local = utctime;
-        if (!ConvertToLocalTime(cx, obj, vp, &local))
-            return JS_FALSE;
-
+        jsdouble local = LocalTime(utctime);
         new_explode(local, &split);
 
         /* let PRMJTime format it.       */
         result_len = PRMJ_FormatTime(buf, sizeof buf, format, &split);
 
         /* If it failed, default to toString. */
         if (result_len == 0)
-            return date_format(cx, obj, utctime, FORMATSPEC_FULL, vp);
+            return date_format(cx, utctime, FORMATSPEC_FULL, vp);
 
         /* Hacked check against undesired 2-digit year 00/00/00 form. */
         if (strcmp(format, "%x") == 0 && result_len >= 6 &&
             /* Format %x means use OS settings, which may have 2-digit yr, so
                hack end of 3/11/22 or 11.03.22 or 11Mar22 to use 4-digit yr...*/
             !isdigit(buf[result_len - 3]) &&
             isdigit(buf[result_len - 2]) && isdigit(buf[result_len - 1]) &&
             /* ...but not if starts with 4-digit year, like 2022/3/11. */
@@ -2001,37 +1911,31 @@ date_toLocaleFormat(JSContext *cx, uintN
         return JS_FALSE;
 
     return date_toLocaleHelper(cx, fmtbytes, vp);
 }
 
 static JSBool
 date_toTimeString(JSContext *cx, uintN argc, jsval *vp)
 {
-    JSObject *obj;
     jsdouble utctime;
 
-    obj = JS_THIS_OBJECT(cx, vp);
-
-    if (!GetUTCTime(cx, obj, vp, &utctime))
+    if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
         return JS_FALSE;
-    return date_format(cx, obj, utctime, FORMATSPEC_TIME, vp);
+    return date_format(cx, utctime, FORMATSPEC_TIME, vp);
 }
 
 static JSBool
 date_toDateString(JSContext *cx, uintN argc, jsval *vp)
 {
-    JSObject *obj;
     jsdouble utctime;
 
-    obj = JS_THIS_OBJECT(cx, vp);
-
-    if (!GetUTCTime(cx, obj, vp, &utctime))
+    if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
         return JS_FALSE;
-    return date_format(cx, obj, utctime, FORMATSPEC_DATE, vp);
+    return date_format(cx, utctime, FORMATSPEC_DATE, vp);
 }
 
 #if JS_HAS_TOSOURCE
 #include <string.h>
 #include "jsdtoa.h"
 
 static JSBool
 date_toSource(JSContext *cx, uintN argc, jsval *vp)
@@ -2063,40 +1967,37 @@ date_toSource(JSContext *cx, uintN argc,
     *vp = STRING_TO_JSVAL(str);
     return JS_TRUE;
 }
 #endif
 
 static JSBool
 date_toString(JSContext *cx, uintN argc, jsval *vp)
 {
-    JSObject *obj;
     jsdouble utctime;
 
-    obj = JS_THIS_OBJECT(cx, vp);
-
-    if (!GetUTCTime(cx, obj, vp, &utctime))
+    if (!GetUTCTime(cx, JS_THIS_OBJECT(cx, vp), vp, &utctime))
         return JS_FALSE;
-    return date_format(cx, obj, utctime, FORMATSPEC_FULL, vp);
+    return date_format(cx, utctime, FORMATSPEC_FULL, vp);
 }
 
 #ifdef JS_TRACER
 static jsval FASTCALL
 date_valueOf_tn(JSContext* cx, JSObject* obj, JSString* str)
 {
     JS_ASSERT(JS_InstanceOf(cx, obj, &js_DateClass, NULL));
     jsdouble t = *JSVAL_TO_DOUBLE(obj->fslots[JSSLOT_UTC_TIME]);
 
     JSString* number_str = ATOM_TO_STRING(cx->runtime->atomState.typeAtoms[JSTYPE_NUMBER]);
     jsval v;
     if (js_EqualStrings(str, number_str)) {
         if (!js_NewNumberInRootedValue(cx, t, &v))
             return JSVAL_ERROR_COOKIE;
     } else {
-        if (!date_format(cx, obj, t, FORMATSPEC_FULL, &v))
+        if (!date_format(cx, t, FORMATSPEC_FULL, &v))
             return JSVAL_ERROR_COOKIE;
     }
     return v;
 }
 #endif
 
 static JSBool
 date_valueOf(JSContext *cx, uintN argc, jsval *vp)
@@ -2196,31 +2097,29 @@ date_constructor(JSContext *cx, JSObject
     jsdouble *date;
 
     date = js_NewWeaklyRootedDouble(cx, 0.0);
     if (!date)
         return NULL;
 
     obj->fslots[JSSLOT_UTC_TIME] = DOUBLE_TO_JSVAL(date);
     obj->fslots[JSSLOT_LOCAL_TIME] = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
-    obj->fslots[JSSLOT_LOCAL_TZA] = DOUBLE_TO_JSVAL(cx->runtime->jsNaN);
-
     return date;
 }
 
 JSBool
 js_Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
 {
     jsdouble *date;
     JSString *str;
     jsdouble d;
 
     /* Date called as function. */
     if (!JS_IsConstructing(cx))
-        return date_format(cx, NULL, NowAsMillis(), FORMATSPEC_FULL, rval);
+        return date_format(cx, NowAsMillis(), FORMATSPEC_FULL, rval);
 
     /* Date called as constructor. */
     if (argc == 0) {
         date = date_constructor(cx, obj);
         if (!date)
             return JS_FALSE;
         *date = NowAsMillis();
     } else if (argc == 1) {
@@ -2238,49 +2137,49 @@ js_Date(JSContext *cx, JSObject *obj, ui
             date = date_constructor(cx, obj);
             if (!date)
                 return JS_FALSE;
 
             str = js_ValueToString(cx, argv[0]);
             if (!str)
                 return JS_FALSE;
 
-            if (!date_parseString(cx, obj, str, date))
+            if (!date_parseString(str, date))
                 *date = *cx->runtime->jsNaN;
             *date = TIMECLIP(*date);
         }
     } else {
         jsdouble *date;
         jsdouble msec_time;
 
         if (!date_msecFromArgs(cx, argc, argv, &msec_time))
             return JS_FALSE;
 
         date = date_constructor(cx, obj);
         if (!date)
             return JS_FALSE;
 
         if (JSDOUBLE_IS_FINITE(msec_time)) {
-            if (!ConvertToUTC(cx, obj, NULL, &msec_time))
-                return JS_FALSE;
-
+            msec_time = UTC(msec_time);
             msec_time = TIMECLIP(msec_time);
         }
 
         *date = msec_time;
     }
     return JS_TRUE;
 }
 
 JSObject *
 js_InitDateClass(JSContext *cx, JSObject *obj)
 {
     JSObject *proto;
     jsdouble *proto_date;
 
+    /* set static LocalTZA */
+    LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
     proto = js_InitClass(cx, obj, NULL, &js_DateClass, js_Date, MAXARGS,
                          NULL, date_methods, NULL, date_static_methods);
     if (!proto)
         return NULL;
 
     /* Alias toUTCString with toGMTString.  (ECMA B.2.6) */
     if (!JS_AliasProperty(cx, proto, "toUTCString", "toGMTString"))
         return NULL;
@@ -2312,35 +2211,21 @@ js_NewDateObjectMsec(JSContext *cx, jsdo
     return obj;
 }
 
 JS_FRIEND_API(JSObject *)
 js_NewDateObject(JSContext* cx, int year, int mon, int mday,
                  int hour, int min, int sec)
 {
     JSObject *obj;
-    jsdouble *date;
     jsdouble msec_time;
 
     JS_ASSERT(mon < 12);
     msec_time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
-
-    obj = js_NewObject(cx, &js_DateClass, NULL, NULL, 0);
-    if (!obj)
-        return NULL;
-
-    date = date_constructor(cx, obj);
-    if (!date)
-        return NULL;
-
-    if (!ConvertToUTC(cx, obj, NULL, &msec_time))
-        return NULL;
-
-    *date = msec_time;
-
+    obj = js_NewDateObjectMsec(cx, UTC(msec_time));
     return obj;
 }
 
 JS_FRIEND_API(JSBool)
 js_DateIsValid(JSContext *cx, JSObject* obj)
 {
     jsdouble utctime;
     return GetUTCTime(cx, obj, NULL, &utctime) && !JSDOUBLE_IS_NaN(utctime);
@@ -2422,46 +2307,40 @@ js_DateGetSeconds(JSContext *cx, JSObjec
 
     return (int) SecFromTime(utctime);
 }
 
 JS_FRIEND_API(void)
 js_DateSetYear(JSContext *cx, JSObject *obj, int year)
 {
     jsdouble local;
-    jsdouble utc;
 
     if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
         return;
 
     /* reset date if it was NaN */
     if (JSDOUBLE_IS_NaN(local))
         local = 0;
 
     local = date_msecFromDate(year,
                               MonthFromTime(local),
                               DateFromTime(local),
                               HourFromTime(local),
                               MinFromTime(local),
                               SecFromTime(local),
                               msFromTime(local));
 
-    utc = local;
-    if (!ConvertToUTC(cx, obj, NULL, &utc))
-        return;
-
     /* SetUTCTime also invalidates local time cache. */
-    SetUTCTime(cx, obj, NULL, utc);
+    SetUTCTime(cx, obj, NULL, UTC(local));
 }
 
 JS_FRIEND_API(void)
 js_DateSetMonth(JSContext *cx, JSObject *obj, int month)
 {
     jsdouble local;
-    jsdouble utc;
 
     JS_ASSERT(month < 12);
 
     if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
         return;
 
     /* bail if date was NaN */
     if (JSDOUBLE_IS_NaN(local))
@@ -2469,130 +2348,98 @@ js_DateSetMonth(JSContext *cx, JSObject 
 
     local = date_msecFromDate(YearFromTime(local),
                               month,
                               DateFromTime(local),
                               HourFromTime(local),
                               MinFromTime(local),
                               SecFromTime(local),
                               msFromTime(local));
-
-    utc = local;
-    if (!ConvertToUTC(cx, obj, NULL, &utc))
-        return;
-
-    SetUTCTime(cx, obj, NULL, utc);
+    SetUTCTime(cx, obj, NULL, UTC(local));
 }
 
 JS_FRIEND_API(void)
 js_DateSetDate(JSContext *cx, JSObject *obj, int date)
 {
     jsdouble local;
-    jsdouble utc;
 
     if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
         return;
 
     if (JSDOUBLE_IS_NaN(local))
         return;
 
     local = date_msecFromDate(YearFromTime(local),
                               MonthFromTime(local),
                               date,
                               HourFromTime(local),
                               MinFromTime(local),
                               SecFromTime(local),
                               msFromTime(local));
-
-    utc = local;
-    if (!ConvertToUTC(cx, obj, NULL, &utc))
-        return;
-
-    SetUTCTime(cx, obj, NULL, utc);
+    SetUTCTime(cx, obj, NULL, UTC(local));
 }
 
 JS_FRIEND_API(void)
 js_DateSetHours(JSContext *cx, JSObject *obj, int hours)
 {
     jsdouble local;
-    jsdouble utc;
 
     if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
         return;
 
     if (JSDOUBLE_IS_NaN(local))
         return;
-
     local = date_msecFromDate(YearFromTime(local),
                               MonthFromTime(local),
                               DateFromTime(local),
                               hours,
                               MinFromTime(local),
                               SecFromTime(local),
                               msFromTime(local));
-
-    utc = local;
-    if (!ConvertToUTC(cx, obj, NULL, &utc))
-        return;
-
-    SetUTCTime(cx, obj, NULL, utc);
+    SetUTCTime(cx, obj, NULL, UTC(local));
 }
 
 JS_FRIEND_API(void)
 js_DateSetMinutes(JSContext *cx, JSObject *obj, int minutes)
 {
     jsdouble local;
-    jsdouble utc;
 
     if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
         return;
 
     if (JSDOUBLE_IS_NaN(local))
         return;
-
     local = date_msecFromDate(YearFromTime(local),
                               MonthFromTime(local),
                               DateFromTime(local),
                               HourFromTime(local),
                               minutes,
                               SecFromTime(local),
                               msFromTime(local));
-
-    utc = local;
-    if (!ConvertToUTC(cx, obj, NULL, &utc))
-        return;
-
-    SetUTCTime(cx, obj, NULL, utc);
+    SetUTCTime(cx, obj, NULL, UTC(local));
 }
 
 JS_FRIEND_API(void)
 js_DateSetSeconds(JSContext *cx, JSObject *obj, int seconds)
 {
     jsdouble local;
-    jsdouble utc;
 
     if (!GetAndCacheLocalTime(cx, obj, NULL, &local))
         return;
 
     if (JSDOUBLE_IS_NaN(local))
         return;
-
     local = date_msecFromDate(YearFromTime(local),
                               MonthFromTime(local),
                               DateFromTime(local),
                               HourFromTime(local),
                               MinFromTime(local),
                               seconds,
                               msFromTime(local));
-
-    utc = local;
-    if (!ConvertToUTC(cx, obj, NULL, &utc))
-            return;
-
-    SetUTCTime(cx, obj, NULL, utc);
+    SetUTCTime(cx, obj, NULL, UTC(local));
 }
 
 JS_FRIEND_API(jsdouble)
 js_DateGetMsecSinceEpoch(JSContext *cx, JSObject *obj)
 {
     jsdouble utctime;
     if (!GetUTCTime(cx, obj, NULL, &utctime))
         return 0;