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 + -
显示快捷键?