📄 date_object.cpp
字号:
switch (id) { case ToString: case ToDateString: 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); } } time_t tv = (time_t)(milli / 1000.0); int ms = int(milli - tv * 1000.0); struct tm *t; if (utc) t = gmtime(&tv); else t = localtime(&tv); switch (id) {#if APPLE_CHANGES && !KWIQ 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: result = String(formatLocaleDate(tv) + " " + formatLocaleTime(tv)); break; case ToLocaleDateString: result = String(formatLocaleDate(tv)); break; case ToLocaleTimeString: result = String(formatLocaleTime(tv)); break;#else case ToString: s = ctime(&tv); result = String(s.substr(0, s.size() - 1)); break; case ToDateString: case ToTimeString: case ToGMTString: case ToUTCString: setlocale(LC_TIME,"C"); if (id == DateProtoFuncImp::ToDateString) { strftime(timebuffer, bufsize, "%x",t); } else if (id == DateProtoFuncImp::ToTimeString) { strftime(timebuffer, bufsize, "%X",t); } else { // toGMTString & toUTCString strftime(timebuffer, bufsize, "%a, %d %b %Y %H:%M:%S %Z", t); } setlocale(LC_TIME,oldlocale.c_str()); result = String(timebuffer); break; case ToLocaleString: strftime(timebuffer, bufsize, "%c", t); result = String(timebuffer); break; case ToLocaleDateString: strftime(timebuffer, bufsize, "%x", t); result = String(timebuffer); break; case ToLocaleTimeString: strftime(timebuffer, bufsize, "%X", t); result = String(timebuffer); break;#endif 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(1900 + t->tm_year); else result = Number(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:#if defined BSD || defined(__APPLE__) result = Number(-t->tm_gmtoff / 60);#else# if defined(__BORLANDC__)#error please add daylight savings offset here! // FIXME: Using the daylight value was wrong for BSD, maybe wrong here too. result = Number(_timezone / 60 - (_daylight ? 60 : 0));# else // FIXME: Using the daylight value was wrong for BSD, maybe wrong here too. result = Number(( timezone / 60 - ( daylight ? 60 : 0 )));# endif#endif break; case SetTime: milli = roundValue(exec,args[0]); result = Number(milli); thisObj.setInternalValue(result); break; case SetMilliSeconds: ms = args[0].toInt32(exec); break; case SetSeconds: t->tm_sec = args[0].toInt32(exec); if (args.size() >= 2) ms = args[1].toInt32(exec); break; case SetMinutes: t->tm_min = args[0].toInt32(exec); if (args.size() >= 2) t->tm_sec = args[1].toInt32(exec); if (args.size() >= 3) ms = args[2].toInt32(exec); break; case SetHours: t->tm_hour = args[0].toInt32(exec); if (args.size() >= 2) t->tm_min = args[1].toInt32(exec); if (args.size() >= 3) t->tm_sec = args[2].toInt32(exec); if (args.size() >= 4) ms = args[3].toInt32(exec); break; case SetDate: t->tm_mday = args[0].toInt32(exec); break; case SetMonth: t->tm_mon = args[0].toInt32(exec); if (args.size() >= 2) t->tm_mday = args[1].toInt32(exec); break; case SetFullYear: t->tm_year = args[0].toInt32(exec) - 1900; if (args.size() >= 2) t->tm_mon = args[1].toInt32(exec); if (args.size() >= 3) t->tm_mday = args[2].toInt32(exec); break; case SetYear: t->tm_year = args[0].toInt32(exec) >= 1900 ? args[0].toInt32(exec) - 1900 : args[0].toInt32(exec); break; } if (id == SetYear || id == SetMilliSeconds || id == SetSeconds || id == SetMinutes || id == SetHours || id == SetDate || id == SetMonth || id == SetFullYear ) { time_t mktimeResult = utc ? timegm(t) : mktime(t); if (mktimeResult == invalidDate) result = Number(NaN); else result = Number(mktimeResult * 1000.0 + ms); 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 Value value; if (numArgs == 0) { // new Date() ECMA 15.9.3.3#if 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 = Number(utc); } else if (numArgs == 1) { UString s = args[0].toString(exec); double d = s.toDouble(); if (isNaN(d)) value = parseDate(s); else value = Number(d); } else { struct tm t; memset(&t, 0, sizeof(t)); 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 = Number(NaN); } else { 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; time_t mktimeResult = mktime(&t); if (mktimeResult == invalidDate) value = Number(NaN); else value = Number(mktimeResult * 1000.0 + ms); } } Object proto = exec->lexicalInterpreter()->builtinDatePrototype(); Object ret(new DateInstanceImp(proto.imp())); ret.setInternalValue(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);#if APPLE_CHANGES && !KWIQ struct tm *tm = localtime(&t); return String(formatDate(*tm) + " " + formatTime(*tm));#else UString s(ctime(&t)); // return formatted string minus trailing \n return String(s.substr(0, s.size() - 1));#endif}// ------------------------------ 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 parseDate(args[0].toString(exec)); } else { // UTC struct tm t; memset(&t, 0, sizeof(t)); 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); } 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; time_t mktimeResult = timegm(&t); if (mktimeResult == invalidDate) return Number(NaN); return Number(mktimeResult * 1000.0 + ms); }}// -----------------------------------------------------------------------------Value KJS::parseDate(const UString &u){#ifdef KJS_VERBOSE fprintf(stderr,"KJS::parseDate %s\n",u.ascii());#endif int firstSlash = u.find('/'); if ( firstSlash == -1 ) { time_t seconds = KRFCDate_parseDate( u );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -