Bug 78717 - Date.UTC and Date.setUTC* produce incorrect time
Summary: Date.UTC and Date.setUTC* produce incorrect time
Status: RESOLVED FIXED
Alias: None
Product: konqueror
Classification: Applications
Component: kjs (show other bugs)
Version: unspecified
Platform: Debian testing Linux
: NOR normal
Target Milestone: ---
Assignee: Konqueror Developers
URL:
Keywords:
: 85652 (view as bug list)
Depends on:
Blocks:
 
Reported: 2004-03-30 06:17 UTC by Gordon Tyler
Modified: 2004-09-30 23:04 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Testcase (935 bytes, text/html)
2004-03-30 06:18 UTC, Gordon Tyler
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Gordon Tyler 2004-03-30 06:17:18 UTC
Version:            (using KDE KDE 3.2.1)
Installed from:    Debian testing/unstable Packages
OS:          Linux

The attached test-case (which can also be found at http://www.doxxx.net/date-test.html) shows 3 snippets of Javascript which each create a Date object in different ways and then display its toString, getTime and toUTCString values.

The second and third snippets show the incorrect time in Konqueror.

Having looked at the KJS code, I believe it is the use of the mktime function at the end of the DateProtoFuncImp:call and DateObjectFuncImp:call functions that is causing the problem, since mktime is defined (in the man page) as expecting the tm struct provided to contain local time but these two KJS functions are putting UTC time into the struct.

I have submitted a similar bug to Apple since Safari displays a similar problem but with only the third snippet of code showing the incorrect time.

For comparison, Firefox shows the correct time for all three snippets.
Comment 1 Gordon Tyler 2004-03-30 06:18:09 UTC
Created attachment 5462 [details]
Testcase
Comment 2 M. Olson 2004-06-01 19:04:27 UTC
Another example:

<script language="JavaScript">
                                                                                                                                                                                                     
var rawstartTime = '<!--#config timefmt="%c" --><!--#echo var="DATE_LOCAL" -->';
var startTime = Date.parse(rawstartTime);
                                                                                                                                                                                                     
 function nextTick()
                                                                                                                                                                                                     
 {
                                                                                                                                                                                                     
   startTime += 1000;
   nisttime = new Date(startTime);
   utcTime = nisttime.toUTCString();
   localeTime = nisttime.toLocaleString();
   gmtTime = nisttime.toGMTString();
   self.status = 'UTC(NIST) Time: ' + nisttime;
                                                                                                                                                                                                     
   window.setTimeout( "nextTick()", 1000 );
                                                                                                                                                                                                     
 }
                                                                                                                                                                                                     
 nextTick();
</script>

To see in action go to:

http://www.oceanconsulting.com/

and look at the status bar.  Works correctly in both IE and Mozilla.
Comment 3 Pascal Létourneau 2004-09-30 17:37:01 UTC
CVS commit by pletourn: 

Fix new Date("01 Jan 2004 10:00")
Fix Date.setUTC*()
Fix Date.UTC()
CCMAIL:78717-done@bugs.kde.org


  M +23 -19    date_object.cpp   1.80.2.2
  M +1 -1      date_object.h   1.22.6.1


--- kdelibs/kjs/date_object.h  #1.22:1.22.6.1
@@ -123,5 +123,5 @@ namespace KJS {
   double KRFCDate_parseDate(const UString &_date);
   Value timeClip(const Value &t);
-  int local_timeoffset();
+  Number makeTime(struct tm *t, int milli, bool utc);
 
 } // namespace

--- kdelibs/kjs/date_object.cpp  #1.80.2.1:1.80.2.2
@@ -380,6 +380,5 @@ Value DateProtoFuncImp::call(ExecState *
       id == SetMinutes || id == SetHours || id == SetDate ||
       id == SetMonth || id == SetFullYear ) {
-    t->tm_isdst = -1; // reset DST
-    result = Number(mktime(t) * 1000.0 + ms);
+    result = makeTime(t, ms, utc);
     thisObj.setInternalValue(result);
   }
@@ -462,5 +461,5 @@ Object DateObjectImp::construct(ExecStat
     t.tm_isdst = -1;
     int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0;
-    value = Number(mktime(&t) * 1000.0 + ms);
+    value = makeTime(&t, ms, false);
   }
 
@@ -522,5 +521,5 @@ Value DateObjectFuncImp::call(ExecState 
     t.tm_sec = (n >= 6) ? args[5].toInt32(exec) : 0;
     int ms = (n >= 7) ? args[6].toInt32(exec) : 0;
-    return Number(mktime(&t) * 1000.0 + ms);
+    return makeTime(&t, ms, true);
   }
 }
@@ -594,17 +593,19 @@ static const struct {
 };
 
-int KJS::local_timeoffset()
+Number KJS::makeTime(struct tm *t, int ms, bool utc)
 {
-     static int local_offset = -1;
-
-     if ( local_offset != -1 ) return local_offset;
-
-     time_t local = time(0);
-     struct tm* tm_local = gmtime(&local);
-     local_offset = local-mktime(tm_local);
-     if(tm_local->tm_isdst)
-       local_offset += 3600;
+    int utcOffset;
+    if (utc) {
+        time_t zero = 0;
+        struct tm t3;
+        localtime_r(&zero, &t3);
+        utcOffset = t3.tm_gmtoff;
+        t->tm_isdst = t3.tm_isdst;
+    } else {
+        utcOffset = 0;
+        t->tm_isdst = -1;
+    }
 
-     return local_offset;
+    return Number( ( mktime(t) + utcOffset ) * 1000.0 + ms );
 }
 
@@ -863,5 +864,5 @@ double KJS::KRFCDate_parseDate(const USt
         return invalidDate;
 
-     if (!have_time && !have_tz) {
+     if (!have_tz) {
        // fall back to midnight, local timezone
        struct tm t;
@@ -871,10 +872,13 @@ double KJS::KRFCDate_parseDate(const USt
        t.tm_year = year - 1900;
        t.tm_isdst = -1;
+       if (have_time) {
+         t.tm_sec = second;
+         t.tm_min = minute;
+         t.tm_hour = hour;
+       }
+            
        return mktime(&t);
      }
 
-     if(!have_tz)
-       offset = local_timeoffset();
-     else
        offset *= 60;
 


Comment 4 Pascal Létourneau 2004-09-30 17:53:22 UTC
*** Bug 85652 has been marked as a duplicate of this bug. ***
Comment 5 Gordon Tyler 2004-09-30 19:53:21 UTC
Excellent news! Any idea which version of KDE will contain the fix?
Comment 6 Matt Rogers 2004-09-30 23:04:16 UTC
KDE 3.3.1