Commit 92285d33 authored by darin's avatar darin

Reviewed by Don and John.

	- fixed 3134449 -- Date.UTC returns NaN (invalid date)

	Did more testing of the date functions and made them behave like the other browsers.
	There were three problems:

            1) We did a validity check that other browsers don't do (hence the NaN).
            2) We treated passed-in dates as local time even in Date.UTC (hence a wrong result
               once I fixed the NaN).
            3) The results of ToUTCString (and ToGMTString) weren't formatted quite the same
	       as other browsers.

	Also found a couple of silly but unrelated coding mistakes.

        * kjs/date_object.cpp:
        (timetUsingCF): Added. Has the guts of mktimeUsingCF, but without the CFGregorianDateIsValid
        check. Other browsers accept invalid dates. Also takes a time zone parameter.
        (mktimeUsingCF): Calls timetUsingCF with the current time zone.
        (timegmUsingCF): Calls timetUsingCF with the UTC time zone.
        (formatDate): Remove the includeComma flag.
        (formatDateUTCVariant): Added. For use instead of formatDate with the includeComma flag.
	Puts the day before the month name.
        (DateProtoFuncImp::call): Use the new formatDateUTCVariant for ToGMTString and ToUTCString.
	Without this change the date didn't match other browsers.
        (DateObjectImp::DateObjectImp): Use UTCPropertyName. Somehow I declared this and didn't use
	it before.
        (DateObjectImp::construct): Pass -1 for is_dst literally instead of using invalidDate.
	Changing this to invalidDate was just a mistake (although no real difference in compiled
	code since invalidDate is just -1).
        (DateObjectFuncImp::call): Call timegm for the UTC case instead of mktime.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@3177 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e72b8ee6
2002-12-22 Darin Adler <darin@apple.com>
Reviewed by Don and John.
- fixed 3134449 -- Date.UTC returns NaN (invalid date)
Did more testing of the date functions and made them behave like the other browsers.
There were three problems:
1) We did a validity check that other browsers don't do (hence the NaN).
2) We treated passed-in dates as local time even in Date.UTC (hence a wrong result
once I fixed the NaN).
3) The results of ToUTCString (and ToGMTString) weren't formatted quite the same
as other browsers.
Also found a couple of silly but unrelated coding mistakes.
* kjs/date_object.cpp:
(timetUsingCF): Added. Has the guts of mktimeUsingCF, but without the CFGregorianDateIsValid
check. Other browsers accept invalid dates. Also takes a time zone parameter.
(mktimeUsingCF): Calls timetUsingCF with the current time zone.
(timegmUsingCF): Calls timetUsingCF with the UTC time zone.
(formatDate): Remove the includeComma flag.
(formatDateUTCVariant): Added. For use instead of formatDate with the includeComma flag.
Puts the day before the month name.
(DateProtoFuncImp::call): Use the new formatDateUTCVariant for ToGMTString and ToUTCString.
Without this change the date didn't match other browsers.
(DateObjectImp::DateObjectImp): Use UTCPropertyName. Somehow I declared this and didn't use
it before.
(DateObjectImp::construct): Pass -1 for is_dst literally instead of using invalidDate.
Changing this to invalidDate was just a mistake (although no real difference in compiled
code since invalidDate is just -1).
(DateObjectFuncImp::call): Call timegm for the UTC case instead of mktime.
=== Alexander-44 ===
=== Alexander-43 ===
......
2002-12-22 Darin Adler <darin@apple.com>
Reviewed by Don and John.
- fixed 3134449 -- Date.UTC returns NaN (invalid date)
Did more testing of the date functions and made them behave like the other browsers.
There were three problems:
1) We did a validity check that other browsers don't do (hence the NaN).
2) We treated passed-in dates as local time even in Date.UTC (hence a wrong result
once I fixed the NaN).
3) The results of ToUTCString (and ToGMTString) weren't formatted quite the same
as other browsers.
Also found a couple of silly but unrelated coding mistakes.
* kjs/date_object.cpp:
(timetUsingCF): Added. Has the guts of mktimeUsingCF, but without the CFGregorianDateIsValid
check. Other browsers accept invalid dates. Also takes a time zone parameter.
(mktimeUsingCF): Calls timetUsingCF with the current time zone.
(timegmUsingCF): Calls timetUsingCF with the UTC time zone.
(formatDate): Remove the includeComma flag.
(formatDateUTCVariant): Added. For use instead of formatDate with the includeComma flag.
Puts the day before the month name.
(DateProtoFuncImp::call): Use the new formatDateUTCVariant for ToGMTString and ToUTCString.
Without this change the date didn't match other browsers.
(DateObjectImp::DateObjectImp): Use UTCPropertyName. Somehow I declared this and didn't use
it before.
(DateObjectImp::construct): Pass -1 for is_dst literally instead of using invalidDate.
Changing this to invalidDate was just a mistake (although no real difference in compiled
code since invalidDate is just -1).
(DateObjectFuncImp::call): Call timegm for the UTC case instead of mktime.
=== Alexander-44 ===
=== Alexander-43 ===
......
......@@ -73,6 +73,7 @@ using KJS::UString;
#define gmtime(x) gmtimeUsingCF(x)
#define localtime(x) localtimeUsingCF(x)
#define mktime(x) mktimeUsingCF(x)
#define timegm(x) timegmUsingCF(x)
#define time(x) timeUsingCF(x)
#define ctime(x) NotAllowedToCallThis()
......@@ -122,7 +123,7 @@ static struct tm *localtimeUsingCF(const time_t *clock)
return result;
}
static time_t mktimeUsingCF(struct tm *tm)
static time_t timetUsingCF(struct tm *tm, CFTimeZoneRef timeZone)
{
CFGregorianDate date;
date.second = tm->tm_sec;
......@@ -134,17 +135,29 @@ static time_t mktimeUsingCF(struct tm *tm)
// CFGregorianDateGetAbsoluteTime will go nuts if the year is too large,
// so we pick an arbitrary cutoff.
if (!CFGregorianDateIsValid(date, kCFGregorianAllUnits) || date.year > 2500) {
if (date.year > 2500) {
return invalidDate;
}
CFTimeZoneRef timeZone = CFTimeZoneCopyDefault();
CFAbsoluteTime absoluteTime = CFGregorianDateGetAbsoluteTime(date, timeZone);
CFRelease(timeZone);
return (time_t)(absoluteTime + kCFAbsoluteTimeIntervalSince1970);
}
static time_t mktimeUsingCF(struct tm *tm)
{
CFTimeZoneRef timeZone = CFTimeZoneCopyDefault();
time_t result = timetUsingCF(tm, timeZone);
CFRelease(timeZone);
return result;
}
static time_t timegmUsingCF(struct tm *tm)
{
static CFTimeZoneRef timeZoneUTC = CFTimeZoneCreateWithName(NULL, CFSTR("UTC"), TRUE);
return timetUsingCF(tm, timeZoneUTC);
}
static time_t timeUsingCF(time_t *clock)
{
time_t result = (time_t)(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970);
......@@ -154,15 +167,24 @@ static time_t timeUsingCF(time_t *clock)
return result;
}
static UString formatDate(struct tm &tm, bool includeComma = false)
static UString formatDate(struct tm &tm)
{
char buffer[100];
snprintf(buffer, sizeof(buffer), "%s%s %s %02d %04d",
weekdayName[(tm.tm_wday + 6) % 7], includeComma ? "," : "",
snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
weekdayName[(tm.tm_wday + 6) % 7],
monthName[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900);
return buffer;
}
static UString formatDateUTCVariant(struct tm &tm)
{
char buffer[100];
snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
weekdayName[(tm.tm_wday + 6) % 7],
tm.tm_mday, monthName[tm.tm_mon], tm.tm_year + 1900);
return buffer;
}
static UString formatTime(struct tm &tm)
{
char buffer[100];
......@@ -376,7 +398,7 @@ Value DateProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args)
break;
case ToGMTString:
case ToUTCString:
result = String(formatDate(*t, true) + " " + formatTime(*t));
result = String(formatDateUTCVariant(*t) + " " + formatTime(*t));
break;
case ToLocaleString:
result = String(formatLocaleDate(tv) + " " + formatLocaleTime(tv));
......@@ -531,7 +553,7 @@ DateObjectImp::DateObjectImp(ExecState *exec,
static const Identifier parsePropertyName("parse");
putDirect(parsePropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::Parse, 1), DontEnum);
static const Identifier UTCPropertyName("UTC");
putDirect("UTC", new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::UTC, 7), DontEnum);
putDirect(UTCPropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::UTC, 7), DontEnum);
// no. of arguments for constructor
putDirect(lengthPropertyName, 7, ReadOnly|DontDelete|DontEnum);
......@@ -594,7 +616,7 @@ Object DateObjectImp::construct(ExecState *exec, const List &args)
t.tm_hour = (numArgs >= 4) ? args[3].toInt32(exec) : 0;
t.tm_min = (numArgs >= 5) ? args[4].toInt32(exec) : 0;
t.tm_sec = (numArgs >= 6) ? args[5].toInt32(exec) : 0;
t.tm_isdst = invalidDate;
t.tm_isdst = -1;
int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0;
time_t mktimeResult = mktime(&t);
if (mktimeResult == invalidDate)
......@@ -678,7 +700,7 @@ Value DateObjectFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &
t.tm_min = (n >= 5) ? args[4].toInt32(exec) : 0;
t.tm_sec = (n >= 6) ? args[5].toInt32(exec) : 0;
int ms = (n >= 7) ? args[6].toInt32(exec) : 0;
time_t mktimeResult = mktime(&t);
time_t mktimeResult = timegm(&t);
if (mktimeResult == invalidDate)
return Number(NaN);
return Number(mktimeResult * 1000.0 + ms);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment