date_object.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,198 行 · 第 1/3 页
CPP
1,198 行
case ToTimeString: case ToGMTString: case ToUTCString: case ToLocaleString: case ToLocaleDateString: case ToLocaleTimeString: return String("Invalid Date"); case ValueOf: case GetTime: case GetYear: case GetFullYear: case GetMonth: case GetDate: case GetDay: case GetHours: case GetMinutes: case GetSeconds: case GetMilliSeconds: case GetTimezoneOffset: return Number(NaN); } } // check whether time value is outside time_t's usual range // make the necessary transformations if necessary int realYearOffset = 0; double milliOffset = 0.0; if (milli < 0 || milli >= timeFromYear(2038)) { // ### ugly and probably not very precise int realYear = yearFromTime(milli); int base = daysInYear(realYear) == 365 ? 2001 : 2000; milliOffset = timeFromYear(base) - timeFromYear(realYear); milli += milliOffset; realYearOffset = realYear - base; } time_t tv = (time_t) floor(milli / 1000.0); double ms = milli - tv * 1000.0; struct tm *t; if ( (id == DateProtoFuncImp::ToGMTString) || (id == DateProtoFuncImp::ToUTCString) ) t = gmtime(&tv); else if (id == DateProtoFuncImp::ToString) t = localtime(&tv); else if (utc) t = gmtime(&tv); else t = localtime(&tv); // we had an out of range year. use that one (plus/minus offset // found by calculating tm_year) and fix the week day calculation if (realYearOffset != 0) { t->tm_year += realYearOffset; milli -= milliOffset; // our own weekday calculation. beware of need for local time. double m = milli; if (!utc) m -= timeZoneOffset(t) * msPerMinute; t->tm_wday = weekDay(m); } // trick gcc. We don't want the Y2K warnings. const char xFormat[] = "%x"; const char cFormat[] = "%c"; switch (id) { case ToString: result = String(formatDate(*t) + " " + formatTime(*t)); break; case ToDateString: result = String(formatDate(*t)); break; case ToTimeString: result = String(formatTime(*t)); break; case ToGMTString: case ToUTCString: result = String(formatDateUTCVariant(*t) + " " + formatTime(*t)); break; case ToLocaleString: strftime(timebuffer, bufsize, cFormat, t); result = String(timebuffer); break; case ToLocaleDateString: strftime(timebuffer, bufsize, xFormat, t); result = String(timebuffer); break; case ToLocaleTimeString: strftime(timebuffer, bufsize, "%X", t); result = String(timebuffer); break; case ValueOf: result = Number(milli); break; case GetTime: result = Number(milli); break; case GetYear: // IE returns the full year even in getYear. if ( exec->dynamicInterpreter()->compatMode() != Interpreter::IECompat ) result = Number(t->tm_year); else result = Number(1900 + t->tm_year); break; case GetFullYear: result = Number(1900 + t->tm_year); break; case GetMonth: result = Number(t->tm_mon); break; case GetDate: result = Number(t->tm_mday); break; case GetDay: result = Number(t->tm_wday); break; case GetHours: result = Number(t->tm_hour); break; case GetMinutes: result = Number(t->tm_min); break; case GetSeconds: result = Number(t->tm_sec); break; case GetMilliSeconds: result = Number(ms); break; case GetTimezoneOffset: result = Number(timeZoneOffset(t)); break; case SetTime: milli = roundValue(exec,args[0]); result = Number(milli); thisObj.setInternalValue(result); break; case SetMilliSeconds: fillStructuresUsingTimeArgs(exec, args, 1, &ms, t); break; case SetSeconds: fillStructuresUsingTimeArgs(exec, args, 2, &ms, t); break; case SetMinutes: fillStructuresUsingTimeArgs(exec, args, 3, &ms, t); break; case SetHours: fillStructuresUsingTimeArgs(exec, args, 4, &ms, t); break; case SetDate: fillStructuresUsingDateArgs(exec, args, 1, &ms, t); break; case SetMonth: fillStructuresUsingDateArgs(exec, args, 2, &ms, t); break; case SetFullYear: fillStructuresUsingDateArgs(exec, args, 3, &ms, t); break; case SetYear: int y = args[0].toInt32(exec); if (y < 1900) { if (y >= 0 && y <= 99) { t->tm_year = y; } else { fillStructuresUsingDateArgs(exec, args, 3, &ms, t); } } else { t->tm_year = y - 1900; } break; } if (id == SetYear || id == SetMilliSeconds || id == SetSeconds || id == SetMinutes || id == SetHours || id == SetDate || id == SetMonth || id == SetFullYear ) { result = Number(makeTime(t, ms, utc)); thisObj.setInternalValue(result); } return result;}// ------------------------------ DateObjectImp --------------------------------// TODO: MakeTime (15.9.11.1) etc. ?DateObjectImp::DateObjectImp(ExecState *exec, FunctionPrototypeImp *funcProto, DatePrototypeImp *dateProto) : InternalFunctionImp(funcProto){ Value protect(this); // ECMA 15.9.4.1 Date.prototype putDirect(prototypePropertyName, dateProto, DontEnum|DontDelete|ReadOnly); static const Identifier parsePropertyName("parse"); putDirect(parsePropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::Parse, 1), DontEnum); static const Identifier UTCPropertyName("UTC"); putDirect(UTCPropertyName, new DateObjectFuncImp(exec,funcProto,DateObjectFuncImp::UTC, 7), DontEnum); // no. of arguments for constructor putDirect(lengthPropertyName, 7, ReadOnly|DontDelete|DontEnum);}bool DateObjectImp::implementsConstruct() const{ return true;}// ECMA 15.9.3Object DateObjectImp::construct(ExecState *exec, const List &args){ int numArgs = args.size();#ifdef KJS_VERBOSE fprintf(stderr,"DateObjectImp::construct - %d args\n", numArgs);#endif double value; if (numArgs == 0) { // new Date() ECMA 15.9.3.3#ifdef HAVE_SYS_TIMEB_H# if defined(__BORLANDC__) struct timeb timebuffer; ftime(&timebuffer);# else struct _timeb timebuffer; _ftime(&timebuffer);# endif double utc = floor((double)timebuffer.time * 1000.0 + (double)timebuffer.millitm);#else struct timeval tv; gettimeofday(&tv, 0L); double utc = floor((double)tv.tv_sec * 1000.0 + (double)tv.tv_usec / 1000.0);#endif value = utc; } else if (numArgs == 1) { Value prim = args[0].toPrimitive(exec); if (prim.isA(StringType)) value = parseDate(prim.toString(exec)); else value = prim.toNumber(exec); } else { if (isNaN(args[0].toNumber(exec)) || isNaN(args[1].toNumber(exec)) || (numArgs >= 3 && isNaN(args[2].toNumber(exec))) || (numArgs >= 4 && isNaN(args[3].toNumber(exec))) || (numArgs >= 5 && isNaN(args[4].toNumber(exec))) || (numArgs >= 6 && isNaN(args[5].toNumber(exec))) || (numArgs >= 7 && isNaN(args[6].toNumber(exec)))) { value = NaN; } else { struct tm t; memset(&t, 0, sizeof(t)); int year = args[0].toInt32(exec); t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; t.tm_mon = args[1].toInt32(exec); t.tm_mday = (numArgs >= 3) ? args[2].toInt32(exec) : 1; 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 = -1; int ms = (numArgs >= 7) ? args[6].toInt32(exec) : 0; value = makeTime(&t, ms, false); } } Object proto = exec->lexicalInterpreter()->builtinDatePrototype(); Object ret(new DateInstanceImp(proto.imp())); ret.setInternalValue(Number(timeClip(value))); return ret;}bool DateObjectImp::implementsCall() const{ return true;}// ECMA 15.9.2Value DateObjectImp::call(ExecState* /*exec*/, Object &/*thisObj*/, const List &/*args*/){#ifdef KJS_VERBOSE fprintf(stderr,"DateObjectImp::call - current time\n");#endif time_t t = time(0L); // FIXME: not threadsafe struct tm *tm = localtime(&t); return String(formatDate(*tm) + " " + formatTime(*tm));}// ------------------------------ DateObjectFuncImp ----------------------------DateObjectFuncImp::DateObjectFuncImp(ExecState* /*exec*/, FunctionPrototypeImp *funcProto, int i, int len) : InternalFunctionImp(funcProto), id(i){ Value protect(this); putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);}bool DateObjectFuncImp::implementsCall() const{ return true;}// ECMA 15.9.4.2 - 3Value DateObjectFuncImp::call(ExecState *exec, Object &/*thisObj*/, const List &args){ if (id == Parse) { return Number(parseDate(args[0].toString(exec))); } else { // UTC int n = args.size(); if (isNaN(args[0].toNumber(exec)) || isNaN(args[1].toNumber(exec)) || (n >= 3 && isNaN(args[2].toNumber(exec))) || (n >= 4 && isNaN(args[3].toNumber(exec))) || (n >= 5 && isNaN(args[4].toNumber(exec))) || (n >= 6 && isNaN(args[5].toNumber(exec))) || (n >= 7 && isNaN(args[6].toNumber(exec)))) { return Number(NaN); } struct tm t; memset(&t, 0, sizeof(t)); int year = args[0].toInt32(exec); t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; t.tm_mon = args[1].toInt32(exec); t.tm_mday = (n >= 3) ? args[2].toInt32(exec) : 1; t.tm_hour = (n >= 4) ? args[3].toInt32(exec) : 0; 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; return Number(makeTime(&t, ms, true)); }}// -----------------------------------------------------------------------------double KJS::parseDate(const UString &u){#ifdef KJS_VERBOSE fprintf(stderr,"KJS::parseDate %s\n",u.ascii());#endif double /*time_t*/ seconds = KRFCDate_parseDate( u ); return seconds == invalidDate ? NaN : seconds * 1000.0;}///// Awful duplication from krfcdate.cpp - we don't link to kdecorestatic double ymdhms_to_seconds(int year, int mon, int day, int hour, int minute, int second){ //printf("year=%d month=%d day=%d hour=%d minute=%d second=%d\n", year, mon, day, hour, minute, second); double ret = (day - 32075) /* days */ + 1461L * (year + 4800L + (mon - 14) / 12) / 4 + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - 3 * ((year + 4900L + (mon - 14) / 12) / 100) / 4 - 2440588; ret = 24*ret + hour; /* hours */ ret = 60*ret + minute; /* minutes */ ret = 60*ret + second; /* seconds */ return ret;}// we follow the recommendation of rfc2822 to consider all// obsolete time zones not listed here equivalent to "-0000"static const struct KnownZone {#ifdef _WIN32 char tzName[4];#else const char tzName[4];#endif int tzOffset;} known_zones[] = { { "UT", 0 }, { "GMT", 0 }, { "EST", -300 }, { "EDT", -240 }, { "CST", -360 }, { "CDT", -300 }, { "MST", -420 }, { "MDT", -360 }, { "PST", -480 }, { "PDT", -420 }};double KJS::makeTime(struct tm *t, double ms, bool utc){ int utcOffset; if (utc) { time_t zero = 0;#if defined BSD || defined(__linux__) || defined(__APPLE__) struct tm t3; localtime_r(&zero, &t3); utcOffset = t3.tm_gmtoff; t->tm_isdst = t3.tm_isdst;#else
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?