date_object.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,198 行 · 第 1/3 页

CPP
1,198
字号
// -*- c-basic-offset: 2 -*-/* *  This file is part of the KDE libraries *  Copyright (C) 1999-2005 Harri Porten (porten@kde.org) *  Copyright (C) 2004 Apple Computer, Inc. * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Lesser General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Lesser General Public License for more details. * *  You should have received a copy of the GNU Lesser General Public *  License along with this library; if not, write to the Free Software *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#if TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else#if HAVE_SYS_TIME_H#include <sys/time.h>#else#  include <time.h># endif#endif#ifdef HAVE_SYS_TIMEB_H#include <sys/timeb.h>#endif#include <errno.h>#ifdef HAVE_SYS_PARAM_H#  include <sys/param.h>#endif // HAVE_SYS_PARAM_H#include <math.h>#include <string.h>#ifdef HAVE_STRINGS_H#  include <strings.h>#endif#include <stdio.h>#include <stdlib.h>#include <locale.h>#include <ctype.h>#include <assert.h>#include <limits.h>#include "date_object.h"#include "error_object.h"#include "operations.h"#include "date_object.lut.h"#ifdef _MSC_VER#  define strncasecmp(a,b,c) _strnicmp(a,b,c)#endifusing namespace KJS;// come constantsconst time_t invalidDate = LONG_MIN;const double hoursPerDay = 24;const double minutesPerHour = 60;const double secondsPerMinute = 60;const double msPerSecond = 1000;const double msPerMinute = msPerSecond * secondsPerMinute;const double msPerHour = msPerMinute * minutesPerHour;const double msPerDay = msPerHour * hoursPerDay;static const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };static const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };static UString formatDate(struct tm &tm){    char buffer[100];    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){    int tz;    char buffer[100];#if defined BSD || defined(__linux__) || defined(__APPLE__)    tz = tm.tm_gmtoff;#else#  if defined(__BORLANDC__)    tz = - _timezone;#  else    tz = - timezone;#  endif#endif    if (tz == 0) {        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", tm.tm_hour, tm.tm_min, tm.tm_sec);    } else {        int offset = tz;        if (offset < 0) {            offset = -offset;        }        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",                tm.tm_hour, tm.tm_min, tm.tm_sec,                tz < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);    }    return UString(buffer);}static int day(double t){  return int(floor(t / msPerDay));}static double dayFromYear(int year){  return 365.0 * (year - 1970)    + floor((year - 1969) / 4.0)    - floor((year - 1901) / 100.0)    + floor((year - 1601) / 400.0);}// depending on whether it's a leap year or notstatic int daysInYear(int year){  if (year % 4 != 0)    return 365;  else if (year % 400 == 0)    return 366;  else if (year % 100 == 0)    return 365;  else    return 366;}// time value of the start of a yeardouble timeFromYear(int year){  return msPerDay * dayFromYear(year);}// year determined by time valueint yearFromTime(double t){  // ### there must be an easier way  // initial guess  int y = 1970 + int(t / (365.25 * msPerDay));  // adjustment  if (timeFromYear(y) > t) {    do {      --y;    } while (timeFromYear(y) > t);  } else {    while (timeFromYear(y + 1) < t)      ++y;  }  return y;}// 0: Sunday, 1: Monday, etc.int weekDay(double t){  int wd = (day(t) + 4) % 7;  if (wd < 0)    wd += 7;  return wd;}static double timeZoneOffset(const struct tm *t){#if defined BSD || defined(__linux__) || defined(__APPLE__)  return -(t->tm_gmtoff / 60);#else#  if defined(__BORLANDC__) || defined(__CYGWIN__)// FIXME consider non one-hour DST change#if !defined(__CYGWIN__)#error please add daylight savings offset here!#endif  return _timezone / 60 - (t->tm_isdst > 0 ? 60 : 0);#  else  return timezone / 60 - (t->tm_isdst > 0 ? 60 : 0 );#  endif#endif}// Converts a list of arguments sent to a Date member function into milliseconds, updating// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.//// Format of member function: f([hour,] [min,] [sec,] [ms])static void fillStructuresUsingTimeArgs(ExecState *exec, const List &args, int maxArgs, double *ms, struct tm *t){    double milliseconds = 0;    int idx = 0;    int numArgs = args.size();        // JS allows extra trailing arguments -- ignore them    if (numArgs > maxArgs)        numArgs = maxArgs;    // hours    if (maxArgs >= 4 && idx < numArgs) {        t->tm_hour = 0;        milliseconds += args[idx++].toInt32(exec) * msPerHour;    }    // minutes    if (maxArgs >= 3 && idx < numArgs) {        t->tm_min = 0;        milliseconds += args[idx++].toInt32(exec) * msPerMinute;    }        // seconds    if (maxArgs >= 2 && idx < numArgs) {        t->tm_sec = 0;        milliseconds += args[idx++].toInt32(exec) * msPerSecond;    }        // milliseconds    if (idx < numArgs) {        milliseconds += roundValue(exec, args[idx]);    } else {        milliseconds += *ms;    }        *ms = milliseconds;}// Converts a list of arguments sent to a Date member function into years, months, and milliseconds, updating// ms (representing milliseconds) and t (representing the rest of the date structure) appropriately.//// Format of member function: f([years,] [months,] [days])static void fillStructuresUsingDateArgs(ExecState *exec, const List &args, int maxArgs, double *ms, struct tm *t){  int idx = 0;  int numArgs = args.size();    // JS allows extra trailing arguments -- ignore them  if (numArgs > maxArgs)    numArgs = maxArgs;    // years  if (maxArgs >= 3 && idx < numArgs) {    t->tm_year = args[idx++].toInt32(exec) - 1900;  }    // months  if (maxArgs >= 2 && idx < numArgs) {    t->tm_mon = args[idx++].toInt32(exec);  }    // days  if (idx < numArgs) {    t->tm_mday = 0;    *ms += args[idx].toInt32(exec) * msPerDay;  }}// ------------------------------ DateInstanceImp ------------------------------const ClassInfo DateInstanceImp::info = {"Date", 0, 0, 0};DateInstanceImp::DateInstanceImp(ObjectImp *proto)  : ObjectImp(proto){}// ------------------------------ DatePrototypeImp -----------------------------const ClassInfo DatePrototypeImp::info = {"Date", &DateInstanceImp::info, &dateTable, 0};/* Source for date_object.lut.h   We use a negative ID to denote the "UTC" variant.@begin dateTable 61  toString		DateProtoFuncImp::ToString		DontEnum|Function	0  toUTCString		DateProtoFuncImp::ToUTCString		DontEnum|Function	0  toDateString		DateProtoFuncImp::ToDateString		DontEnum|Function	0  toTimeString		DateProtoFuncImp::ToTimeString		DontEnum|Function	0  toLocaleString	DateProtoFuncImp::ToLocaleString	DontEnum|Function	0  toLocaleDateString	DateProtoFuncImp::ToLocaleDateString	DontEnum|Function	0  toLocaleTimeString	DateProtoFuncImp::ToLocaleTimeString	DontEnum|Function	0  valueOf		DateProtoFuncImp::ValueOf		DontEnum|Function	0  getTime		DateProtoFuncImp::GetTime		DontEnum|Function	0  getFullYear		DateProtoFuncImp::GetFullYear		DontEnum|Function	0  getUTCFullYear	-DateProtoFuncImp::GetFullYear		DontEnum|Function	0  toGMTString		DateProtoFuncImp::ToGMTString		DontEnum|Function	0  getMonth		DateProtoFuncImp::GetMonth		DontEnum|Function	0  getUTCMonth		-DateProtoFuncImp::GetMonth		DontEnum|Function	0  getDate		DateProtoFuncImp::GetDate		DontEnum|Function	0  getUTCDate		-DateProtoFuncImp::GetDate		DontEnum|Function	0  getDay		DateProtoFuncImp::GetDay		DontEnum|Function	0  getUTCDay		-DateProtoFuncImp::GetDay		DontEnum|Function	0  getHours		DateProtoFuncImp::GetHours		DontEnum|Function	0  getUTCHours		-DateProtoFuncImp::GetHours		DontEnum|Function	0  getMinutes		DateProtoFuncImp::GetMinutes		DontEnum|Function	0  getUTCMinutes		-DateProtoFuncImp::GetMinutes		DontEnum|Function	0  getSeconds		DateProtoFuncImp::GetSeconds		DontEnum|Function	0  getUTCSeconds		-DateProtoFuncImp::GetSeconds		DontEnum|Function	0  getMilliseconds	DateProtoFuncImp::GetMilliSeconds	DontEnum|Function	0  getUTCMilliseconds	-DateProtoFuncImp::GetMilliSeconds	DontEnum|Function	0  getTimezoneOffset	DateProtoFuncImp::GetTimezoneOffset	DontEnum|Function	0  setTime		DateProtoFuncImp::SetTime		DontEnum|Function	1  setMilliseconds	DateProtoFuncImp::SetMilliSeconds	DontEnum|Function	1  setUTCMilliseconds	-DateProtoFuncImp::SetMilliSeconds	DontEnum|Function	1  setSeconds		DateProtoFuncImp::SetSeconds		DontEnum|Function	2  setUTCSeconds		-DateProtoFuncImp::SetSeconds		DontEnum|Function	2  setMinutes		DateProtoFuncImp::SetMinutes		DontEnum|Function	3  setUTCMinutes		-DateProtoFuncImp::SetMinutes		DontEnum|Function	3  setHours		DateProtoFuncImp::SetHours		DontEnum|Function	4  setUTCHours		-DateProtoFuncImp::SetHours		DontEnum|Function	4  setDate		DateProtoFuncImp::SetDate		DontEnum|Function	1  setUTCDate		-DateProtoFuncImp::SetDate		DontEnum|Function	1  setMonth		DateProtoFuncImp::SetMonth		DontEnum|Function	2  setUTCMonth		-DateProtoFuncImp::SetMonth		DontEnum|Function	2  setFullYear		DateProtoFuncImp::SetFullYear		DontEnum|Function	3  setUTCFullYear	-DateProtoFuncImp::SetFullYear		DontEnum|Function	3  setYear		DateProtoFuncImp::SetYear		DontEnum|Function	1  getYear		DateProtoFuncImp::GetYear		DontEnum|Function	0  toGMTString		DateProtoFuncImp::ToGMTString		DontEnum|Function	0@end*/// ECMA 15.9.4DatePrototypeImp::DatePrototypeImp(ExecState *,                                   ObjectPrototypeImp *objectProto)  : DateInstanceImp(objectProto){  Value protect(this);  setInternalValue(Number(NaN));  // The constructor will be added later, after DateObjectImp has been built}Value DatePrototypeImp::get(ExecState *exec, const Identifier &propertyName) const{  return lookupGetFunction<DateProtoFuncImp, ObjectImp>( exec, propertyName, &dateTable, this );}// ------------------------------ DateProtoFuncImp -----------------------------DateProtoFuncImp::DateProtoFuncImp(ExecState *exec, int i, int len)  : InternalFunctionImp(    static_cast<FunctionPrototypeImp*>(exec->lexicalInterpreter()->builtinFunctionPrototype().imp())    ), id(abs(i)), utc(i<0)  // We use a negative ID to denote the "UTC" variant.{  Value protect(this);  putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);}bool DateProtoFuncImp::implementsCall() const{  return true;}Value DateProtoFuncImp::call(ExecState *exec, Object &thisObj, const List &args){  if ((id == ToString || id == ValueOf || id == GetTime || id == SetTime) &&      !thisObj.inherits(&DateInstanceImp::info)) {    // non-generic function called on non-date object    // ToString and ValueOf are generic according to the spec, but the mozilla    // tests suggest otherwise...    Object err = Error::create(exec,TypeError);    exec->setException(err);    return err;  }  Value result;  UString s;  const int bufsize=100;  char timebuffer[bufsize];  CString oldlocale = setlocale(LC_TIME,NULL);  if (!oldlocale.c_str())    oldlocale = setlocale(LC_ALL, NULL);  Value v = thisObj.internalValue();  double milli = v.toNumber(exec);  // special case: time value is NaN  if (isNaN(milli)) {    switch (id) {    case ToString:    case ToDateString:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?