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