Reviewed by Geoff.
authorkmccullo <kmccullo@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Oct 2006 17:58:09 +0000 (17:58 +0000)
committerkmccullo <kmccullo@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 12 Oct 2006 17:58:09 +0000 (17:58 +0000)
        Added our own tm struct to have a consistent set of fields, which lets us display the DST offset and timezone strings correctly.  Also there is some code cleanup.

        * kjs/DateMath.cpp:
        (KJS::timeToMS):
        (KJS::getUTCOffset):
        (KJS::getDSTOffsetSimple):
        (KJS::dateToMS):
        (KJS::msToTM):
        (KJS::tmToKJStm):
        (KJS::KJStmToTm):
        * kjs/DateMath.h:
        * kjs/date_object.cpp:
        (KJS::gmtoffset):
        (KJS::formatTime):
        (KJS::DateProtoFunc::callAsFunction):
        (KJS::DateObjectImp::construct):
        (KJS::DateObjectImp::callAsFunction):
        (KJS::DateObjectFuncImp::callAsFunction):
        (KJS::parseDate):
        * kjs/date_object.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@17010 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/kjs/DateMath.cpp
JavaScriptCore/kjs/DateMath.h
JavaScriptCore/kjs/date_object.cpp
JavaScriptCore/kjs/date_object.h

index d542a9317c9d1bbe368edfb271db2371de71a16b..643457c0dd51083a6ba66ffdf4d3cba86d8d7ec8 100644 (file)
@@ -1,3 +1,28 @@
+2006-10-11  Kevin McCullough  <KMcCullough@apple.com>
+
+        Reviewed by Geoff.
+
+        Added our own tm struct to have a consistent set of fields, which lets us display the DST offset and timezone strings correctly.  Also there is some code cleanup.
+
+        * kjs/DateMath.cpp:
+        (KJS::timeToMS):
+        (KJS::getUTCOffset):
+        (KJS::getDSTOffsetSimple):
+        (KJS::dateToMS):
+        (KJS::msToTM):
+        (KJS::tmToKJStm):
+        (KJS::KJStmToTm):
+        * kjs/DateMath.h:
+        * kjs/date_object.cpp: 
+        (KJS::gmtoffset): 
+        (KJS::formatTime): 
+        (KJS::DateProtoFunc::callAsFunction): 
+        (KJS::DateObjectImp::construct):
+        (KJS::DateObjectImp::callAsFunction):
+        (KJS::DateObjectFuncImp::callAsFunction):
+        (KJS::parseDate):
+        * kjs/date_object.h:
+
 2006-10-09  Krzysztof Kowalczyk  <kkowalczyk@gmail.com>
 
         Reviewed by Geoff.
index 8f31c63e71f4115add1632e33e497d7d531b4b20..245afb2a05b935a678cdbe101c43e13f92ace61a 100644 (file)
@@ -270,7 +270,7 @@ static inline int monthToDayInYear(int month, bool isLeapYear)
     return firstDayOfMonth[isLeapYear][month];
 }
 
-static inline double timeToMseconds(double hour, double min, double sec, double ms)
+static inline double timeToMS(double hour, double min, double sec, double ms)
 {
     return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms);
 }
@@ -319,25 +319,14 @@ double getUTCOffset() {
     static double utcOffset;
     static bool utcOffsetInitialized = false;
     if (!utcOffsetInitialized) {
-        struct tm ltime;
-
-        ltime.tm_sec = 0;
-        ltime.tm_min = 0;
-        ltime.tm_hour = 0;
-        ltime.tm_mon = 0;
-        ltime.tm_wday = 0;
-        ltime.tm_yday = 0;
-        ltime.tm_isdst = 0;
+        struct ::tm ltime;
 
+        memset(&ltime, 0, sizeof(ltime));
+        
         // get the difference between this time zone and GMT 
         ltime.tm_mday = 2;
         ltime.tm_year = 70;
 
-#if !PLATFORM(WIN_OS)
-        ltime.tm_zone = 0;
-        ltime.tm_gmtoff = 0;
-#endif
-
         utcOffset = mktime(&ltime) - (hoursPerDay * secondsPerHour);
         utcOffset *= -msPerSecond;
 
@@ -358,23 +347,23 @@ static double getDSTOffsetSimple(double localTimeSeconds)
     else if(localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0)
         localTimeSeconds += secondsPerDay;
 
-    struct tm prtm;
     double offsetTime = (localTimeSeconds * usecPerMsec) + getUTCOffset() ;
 
-    prtm.tm_hour  =  msToHours(offsetTime);
-    prtm.tm_min   =  msToMinutes(offsetTime);
+    // Offset from UTC but doesn't include DST obviously
+    int offsetHour =  msToHours(offsetTime);
+    int offsetMinute =  msToMinutes(offsetTime);
 
     // FIXME: time_t has a potential problem in 2038
     time_t localTime = static_cast<time_t>(localTimeSeconds);
 
-    struct tm tm;
+    struct ::tm tm;
     #if PLATFORM(WIN_OS)
     localtime_s(&tm, &localTime);
     #else
     localtime_r(&localTime, &tm);
     #endif
-
-    double diff = ((tm.tm_hour - prtm.tm_hour) * secondsPerHour) + ((tm.tm_min - prtm.tm_min) * 60);
+    
+    double diff = ((tm.tm_hour - offsetHour) * secondsPerHour) + ((tm.tm_min - offsetMinute) * 60);
 
     if(diff < 0)
         diff += secondsPerDay;
@@ -382,7 +371,8 @@ static double getDSTOffsetSimple(double localTimeSeconds)
     return (diff * usecPerMsec);
 }
 
-// get the DST offset the time passed in
+// Get the DST offset the time passed in
+// ms is in UTC
 static double getDSTOffset(double ms)
 {
     /*
@@ -401,14 +391,15 @@ static double getDSTOffset(double ms)
     return getDSTOffsetSimple(ms / usecPerMsec);
 }
 
-double dateToMseconds(tm* t, double ms, bool inputIsUTC)
+double dateToMS(const tm& t, double milliSeconds, bool inputIsUTC)
 {
-    int day = dateToDayInYear(t->tm_year + 1900, t->tm_mon, t->tm_mday);
-    double msec_time = timeToMseconds(t->tm_hour, t->tm_min, t->tm_sec, ms);
-    double result = (day * msPerDay) + msec_time;
+
+    int day = dateToDayInYear(t.tm_year + 1900, t.tm_mon, t.tm_mday);
+    double ms = timeToMS(t.tm_hour, t.tm_min, t.tm_sec, milliSeconds);
+    double result = (day * msPerDay) + ms;
 
     if(!inputIsUTC) { // convert to UTC
-        result -= getUTCOffset();
+        result -= getUTCOffset();       
         result -= getDSTOffset(result);
     }
 
@@ -435,15 +426,55 @@ void msToTM(double ms, bool outputIsUTC, struct tm& tm)
     tm.tm_year  =  msToYear(ms) - 1900;
     tm.tm_isdst =  dstOff != 0.0;
 
-    // All other OS' seems to have these fields
+    tm.tm_gmtoff = (dstOff + getUTCOffset()) / usecPerMsec;
+    tm.tm_zone = 0;
+}
+
+// converting between the two tm structures
+tm tmToKJStm(const struct ::tm& inTm)
+{
+    struct tm ret;
+    memset(&ret, 0, sizeof(ret));
+
+    ret.tm_sec   =  inTm.tm_sec;
+    ret.tm_min   =  inTm.tm_min;
+    ret.tm_hour  =  inTm.tm_hour;
+    ret.tm_wday  =  inTm.tm_wday;
+    ret.tm_mday  =  inTm.tm_mday;
+    ret.tm_yday  =  inTm.tm_yday;
+    ret.tm_mon   =  inTm.tm_mon;
+    ret.tm_year  =  inTm.tm_year;
+    ret.tm_isdst =  inTm.tm_isdst;
+
 #if !PLATFORM(WIN_OS)
-    struct tm xtm;
-    // FIXME: time_t has a potential problem in 2038
-    time_t seconds = static_cast<time_t>(ms/usecPerMsec);
-    localtime_r(&seconds, &xtm);
-    tm.tm_gmtoff = xtm.tm_gmtoff;
-    tm.tm_zone = xtm.tm_zone;
+    ret.tm_gmtoff = inTm.tm_gmtoff;
+    ret.tm_zone = inTm.tm_zone;
+#endif
+
+    return ret;
+}
+
+::tm KJStmToTm(const struct tm& inTm)
+{
+    struct ::tm ret;
+    memset(&ret, 0, sizeof(ret));
+
+    ret.tm_sec   =  inTm.tm_sec;
+    ret.tm_min   =  inTm.tm_min;
+    ret.tm_hour  =  inTm.tm_hour;
+    ret.tm_wday  =  inTm.tm_wday;
+    ret.tm_mday  =  inTm.tm_mday;
+    ret.tm_yday  =  inTm.tm_yday;
+    ret.tm_mon   =  inTm.tm_mon;
+    ret.tm_year  =  inTm.tm_year;
+    ret.tm_isdst =  inTm.tm_isdst;
+
+#if !PLATFORM(WIN_OS)
+    ret.tm_gmtoff = inTm.tm_gmtoff;
+    ret.tm_zone = inTm.tm_zone;
 #endif
+
+    return ret;
 }
 
 }   // namespace KJS
index a0b0447c678bcd893517e73ba27fb391c9655a88..be526452107fcf76b858b96d05d663754297d65b 100644 (file)
 
 namespace KJS {
 
+// Intentionally overridding the default tm of the system
+// Not all OS' have the same members of their tm's
+struct tm {
+    int tm_sec;
+    int tm_min;
+    int tm_hour;
+    int tm_wday;
+    int tm_mday;
+    int tm_yday;
+    int tm_mon;
+    int tm_year;
+    int tm_isdst;
+    long tm_gmtoff;
+    char* tm_zone;
+};
+
 // Constants //
 
 const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
@@ -60,9 +76,12 @@ const double msPerHour = 60.0 * 60.0 * 1000.0;
 
 // Exported Functions //
 void msToTM(double, bool outputIsUTC, struct tm& );
-double dateToMseconds(tm*, double, bool inputIsUTC);
+double dateToMS(const tm&, double, bool inputIsUTC);
 double getUTCOffset();
 
+tm tmToKJStm(const struct ::tm&);
+::tm KJStmToTm(const struct tm&);
+
 }   //namespace KJS
 
 #endif // DateMath_h
index 7008c75c3c99925bc33c66035837b7771482750d..06f23dc3e4cc779e717082bbec81d2202f7a4d49 100644 (file)
@@ -67,12 +67,7 @@ static double timeClip(double);
 
 inline int gmtoffset(const tm& t)
 {
-#if PLATFORM(WIN_OS)
-    // Time is supposed to be in the current timezone.
-    return -(_timezone / 60 - (t.tm_isdst != 0 ? 60 : 0 )) * 60;
-#else
     return t.tm_gmtoff;
-#endif
 }
 
 
@@ -186,12 +181,10 @@ static UString formatTime(const tm &t, bool utc)
         snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.tm_hour, t.tm_min, t.tm_sec);
     } else {
         int offset = abs(gmtoffset(t));
-#if PLATFORM(WIN_OS)
         char tzname[70];
-        strftime(tzname, sizeof(tzname), "%Z", &t);
-#else
-        const char *tzname = t.tm_zone;
-#endif
+        struct ::tm gtm = KJStmToTm(t);
+        strftime(tzname, sizeof(tzname), "%Z", &gtm);
+
         if (tzname) {
             snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
                 t.tm_hour, t.tm_min, t.tm_sec,
@@ -486,18 +479,24 @@ JSValue *DateProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const
     return jsString(formatLocaleDate(exec, secs, false, true, args));
     break;
 #else
-  case ToLocaleString:
-    strftime(timebuffer, bufsize, "%c", &t);
+  case ToLocaleString: {
+    struct ::tm gtm = KJStmToTm(t);
+    strftime(timebuffer, bufsize, "%c", &gtm);
     return jsString(timebuffer);
     break;
-  case ToLocaleDateString:
-    strftime(timebuffer, bufsize, "%x", &t);
+    }
+  case ToLocaleDateString: {
+    struct ::tm gtm = KJStmToTm(t);
+    strftime(timebuffer, bufsize, "%x", &gtm);
     return jsString(timebuffer);
     break;
-  case ToLocaleTimeString:
-    strftime(timebuffer, bufsize, "%X", &t);
+    }
+  case ToLocaleTimeString: {
+    struct ::tm gtm = KJStmToTm(t);
+    strftime(timebuffer, bufsize, "%X", &gtm);
     return jsString(timebuffer);
     break;
+    }
 #endif
   case ValueOf:
   case GetTime:
@@ -559,7 +558,7 @@ JSValue *DateProtoFunc::callAsFunction(ExecState *exec, JSObject *thisObj, const
   if (id == SetYear || id == SetMilliSeconds || id == SetSeconds ||
       id == SetMinutes || id == SetHours || id == SetDate ||
       id == SetMonth || id == SetFullYear ) {
-    result = jsNumber(dateToMseconds(&t, ms, utc));
+    result = jsNumber(dateToMS(t, ms, utc));
     thisDateObj->setInternalValue(result);
   }
   
@@ -646,7 +645,7 @@ JSObject *DateObjectImp::construct(ExecState *exec, const List &args)
       t.tm_sec = (numArgs >= 6) ? args[5]->toInt32(exec) : 0;
       t.tm_isdst = -1;
       double ms = (numArgs >= 7) ? roundValue(exec, args[6]) : 0;
-      value = dateToMseconds(&t, ms, false);
+      value = dateToMS(t, ms, false);
     }
   }
   
@@ -659,7 +658,7 @@ JSObject *DateObjectImp::construct(ExecState *exec, const List &args)
 JSValue *DateObjectImp::callAsFunction(ExecState * /*exec*/, JSObject * /*thisObj*/, const List &/*args*/)
 {
     time_t t = time(0);
-    tm ts = *localtime(&t);
+    tm ts = tmToKJStm(*localtime(&t));
     return jsString(formatDate(ts) + " " + formatTime(ts, false));
 }
 
@@ -699,7 +698,7 @@ JSValue *DateObjectFuncImp::callAsFunction(ExecState* exec, JSObject*, const Lis
     t.tm_min = (n >= 5) ? args[4]->toInt32(exec) : 0;
     t.tm_sec = (n >= 6) ? args[5]->toInt32(exec) : 0;
     double ms = (n >= 7) ? roundValue(exec, args[6]) : 0;
-    return jsNumber(dateToMseconds(&t, ms, true));
+    return jsNumber(dateToMS(t, ms, true));
   }
 }
 
@@ -1066,8 +1065,8 @@ static double parseDate(const UString &date)
         t.tm_min = minute;
         t.tm_hour = hour;
 
-        // Use our dateToMseconds() rather than mktime() as the latter can't handle the full year range.
-        return dateToMseconds(&t, 0, false);
+        // Use our dateToMS() rather than mktime() as the latter can't handle the full year range.
+        return dateToMS(t, 0, false);
     }
 
     return (ymdhmsToSeconds(year, month + 1, day, hour, minute, second) - (offset * 60.0)) * msPerSecond;
index 9f44e78cdd563510f952aaaac0cb4e5d285c72cd..deaaa4708869452d08a9d2eaa9dfa22d0e4b3312 100644 (file)
@@ -26,6 +26,8 @@
 
 namespace KJS {
 
+    struct tm;
+
     class FunctionPrototype;
     class ObjectPrototype;