date_object.cpp
来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 467 行
CPP
467 行
/* * This file is part of the KDE libraries * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifndef HAVE_SYS_TIMEB_H#define HAVE_SYS_TIMEB_H 0#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#if HAVE_SYS_TIMEB_H#include <sys/timeb.h>#endif#ifdef HAVE_SYS_PARAM_H# include <sys/param.h>#endif // HAVE_SYS_PARAM_H#include <math.h>#include <string.h>#include <stdio.h>#include <locale.h>#include "kjs.h"#include "date_object.h"namespace KJS { class DateObjectFunc : public InternalFunctionImp { public: DateObjectFunc(int i) : id(i) { }; Completion execute(const List &); enum { Parse, UTC }; private: int id; }; class DateProtoFunc : public InternalFunctionImp { public: DateProtoFunc(int i, bool u); Completion execute(const List &); enum { ToString, ToDateString, ToTimeString, ToLocaleString, ToLocaleDateString, ToLocaleTimeString, ValueOf, GetTime, GetFullYear, GetMonth, GetDate, GetDay, GetHours, GetMinutes, GetSeconds, GetMilliSeconds, GetTimezoneOffset, SetTime, SetMilliSeconds, SetSeconds, SetMinutes, SetHours, SetDate, SetMonth, SetFullYear, ToUTCString, // non-normative properties (Appendix B) GetYear, SetYear, ToGMTString }; private: int id; bool utc; }; // helper functions KJSO parseDate(const String &s); KJSO timeClip(const KJSO &t);};using namespace KJS;KJSO KJS::parseDate(const String &s){ UString u = s.value(); int firstSlash = u.find('/'); if ( firstSlash == -1 ) { /* TODO parse dates like "December 25, 1995 23:15:00"*/ fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii()); return Number(0); } else { // Found 12/31/2099 on some website -> obviously MM/DD/YYYY int month = u.substr(0,firstSlash).toULong(); int secondSlash = u.find('/',firstSlash+1); //fprintf(stdout,"KJS::parseDate firstSlash=%d, secondSlash=%d\n", firstSlash, secondSlash); if ( secondSlash == -1 ) { fprintf(stderr,"KJS::parseDate parsing for this format isn't implemented\n%s", u.ascii()); return Number(0); } int day = u.substr(firstSlash+1,secondSlash-firstSlash-1).toULong(); int year = u.substr(secondSlash+1).toULong(); //fprintf(stdout,"KJS::parseDate day=%d, month=%d, year=%d\n", day, month, year); struct tm t; memset( &t, 0, sizeof(t) ); year = (year > 2037) ? 2037 : year; // mktime is limited to 2037 !!! t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; t.tm_mon = month-1; // mktime wants 0-11 for some reason t.tm_mday = day; time_t seconds = mktime(&t); if ( seconds == -1 ) { fprintf(stderr,"KJS::parseDate mktime returned -1.\n%s", u.ascii()); return Undefined(); } else return Number(seconds * 1000.0); }}KJSO KJS::timeClip(const KJSO &t){ /* TODO */ return t;}DateObject::DateObject(const Object& funcProto, const Object &dateProto) : ConstructorImp(funcProto, 7){ // ECMA 15.9.4.1 Date.prototype setPrototypeProperty(dateProto);}// ECMA 15.9.2Completion DateObject::execute(const List &){ time_t t = time(0L); UString s(ctime(&t)); // return formatted string minus trailing \n return Completion(ReturnValue, String(s.substr(0, s.size() - 1)));}// ECMA 15.9.3Object DateObject::construct(const List &args){ KJSO value; int numArgs = args.size(); 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) { KJSO p = args[0].toPrimitive(); if (p.isA(StringType)) value = parseDate(p.toString()); else value = p.toNumber(); } else { struct tm t; memset(&t, 0, sizeof(t)); Number y = args[0].toNumber(); /* TODO: check for NaN */ int year = y.toInt32(); t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; t.tm_mon = args[1].toInt32(); t.tm_mday = (numArgs >= 3) ? args[2].toInt32() : 1; t.tm_hour = (numArgs >= 4) ? args[3].toInt32() : 0; t.tm_min = (numArgs >= 5) ? args[4].toInt32() : 0; t.tm_sec = (numArgs >= 6) ? args[5].toInt32() : 0; t.tm_isdst = -1; int ms = (numArgs >= 7) ? args[6].toInt32() : 0; value = Number(mktime(&t) * 1000.0 + ms); } return Object::create(DateClass, timeClip(value));}KJSO DateObject::get(const UString &p) const{ int id; if (p == "parse") id = DateObjectFunc::Parse; else if (p == "UTC") id = DateObjectFunc::UTC; else return Imp::get(p); return Function(new DateObjectFunc(id));}// ECMA 15.9.4.2 - 3Completion DateObjectFunc::execute(const List &args){ KJSO result; if (id == Parse) if (args[0].isA(StringType)) result = parseDate(args[0].toString()); else result = Undefined(); else { struct tm t; memset(&t, 0, sizeof(t)); int n = args.size(); Number y = args[0].toNumber(); /* TODO: check for NaN */ int year = y.toInt32(); t.tm_year = (year >= 0 && year <= 99) ? year : year - 1900; t.tm_mon = args[1].toInt32(); t.tm_mday = (n >= 3) ? args[2].toInt32() : 1; t.tm_hour = (n >= 4) ? args[3].toInt32() : 0; t.tm_min = (n >= 5) ? args[4].toInt32() : 0; t.tm_sec = (n >= 6) ? args[5].toInt32() : 0; int ms = (n >= 7) ? args[6].toInt32() : 0; result = Number(mktime(&t) * 1000.0 + ms); } return Completion(ReturnValue, result);}// ECMA 15.9.4DatePrototype::DatePrototype(const Object& proto) : ObjectImp(DateClass, Number(NaN), proto){ // The constructor will be added later in DateObject's constructor}KJSO DatePrototype::get(const UString &p) const{ int id; if (p == "toString" || p == "toUTCString") id = DateProtoFunc::ToString; else if (p == "toDateString") id = DateProtoFunc::ToDateString; else if (p == "toTimeString") id = DateProtoFunc::ToTimeString; else if (p == "toLocaleString") id = DateProtoFunc::ToLocaleString; else if (p == "toLocaleDateString") id = DateProtoFunc::ToLocaleDateString; else if (p == "toLocaleTimeString") id = DateProtoFunc::ToLocaleTimeString; else if (p == "valueOf") id = DateProtoFunc::ValueOf; else if (p == "getTime") id = DateProtoFunc::GetTime; else if (p == "getFullYear" || p == "getUTCFullYear") id = DateProtoFunc::GetFullYear; else if (p == "toGMTString") id = DateProtoFunc::ToGMTString; else if (p == "getMonth" || p == "getUTCMonth") id = DateProtoFunc::GetMonth; else if (p == "getDate" || p == "getUTCDate") id = DateProtoFunc::GetDate; else if (p == "getDay" || p == "getUTCDay") id = DateProtoFunc::GetDay; else if (p == "getHours" || p == "getUTCHours") id = DateProtoFunc::GetHours; else if (p == "getMinutes" || p == "getUTCMinutes") id = DateProtoFunc::GetMinutes; else if (p == "getSeconds" || p == "getUTCSeconds") id = DateProtoFunc::GetSeconds; else if (p == "getMilliseconds" || p == "getUTCMilliseconds") id = DateProtoFunc::GetMilliSeconds; else if (p == "getTimezoneOffset") id = DateProtoFunc::GetTimezoneOffset; else if (p == "setTime") id = DateProtoFunc::SetTime; else if (p == "setMilliseconds" || p == "setUTCMilliseconds") id = DateProtoFunc::SetMilliSeconds; else if (p == "setSeconds" || p == "setUTCSeconds") id = DateProtoFunc::SetSeconds; else if (p == "setMinutes" || p == "setUTCMinutes") id = DateProtoFunc::SetMinutes; else if (p == "setHours" || p == "setUTCHours") id = DateProtoFunc::SetHours; else if (p == "setDate" || p == "setUTCDate") id = DateProtoFunc::SetDate; else if (p == "setMonth" || p == "setUTCMonth") id = DateProtoFunc::SetMonth; else if (p == "setFullYear" || p == "setUTCFullYear") id = DateProtoFunc::SetFullYear; else if (p == "setYear" ) id = DateProtoFunc::SetYear; // non-normative else if (p == "getYear") id = DateProtoFunc::GetYear; else if (p == "toGMTString") id = DateProtoFunc::ToGMTString; else return Undefined(); bool utc = (p.find("UTC") >= 0) ? true : false; return Function(new DateProtoFunc(id, utc));}DateProtoFunc::DateProtoFunc(int i, bool u) : id(i), utc(u){}Completion DateProtoFunc::execute(const List &args){ KJSO result; UString s; const int bufsize=100; char timebuffer[bufsize]; char *oldlocale = setlocale(LC_TIME,NULL); if (!oldlocale) oldlocale = setlocale(LC_ALL, NULL); Object thisObj = Object::dynamicCast(thisValue()); KJSO v = thisObj.internalValue(); double milli = v.toNumber().value(); time_t tv = (time_t) floor(milli / 1000.0); int ms = int(milli - tv * 1000.0); struct tm *t; if (utc) t = gmtime(&tv); else t = localtime(&tv); switch (id) { case ToString: s = ctime(&tv); result = String(s.substr(0, s.size() - 1)); break; case ToDateString: case ToTimeString: case ToGMTString: setlocale(LC_TIME,"C"); if (id == DateProtoFunc::ToDateString) { strftime(timebuffer, bufsize, "%x",t); } else if (id == DateProtoFunc::ToTimeString) { strftime(timebuffer, bufsize, "%X",t); } else { t = gmtime(&tv); strftime(timebuffer, bufsize, "%a, %d-%b-%y %H:%M:%S %Z", t); } setlocale(LC_TIME,oldlocale); 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; case ValueOf: result = Number(milli); break; case GetTime: if (thisObj.getClass() == DateClass) result = Number(milli); else result = Error::create(TypeError); break; case GetYear: 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 = Undefined(); break; case GetTimezoneOffset:#if defined BSD || defined(__APPLE__) result = Number(-( t->tm_gmtoff / 60 ) + ( t->tm_isdst ? 60 : 0 ));#else# if defined(__BORLANDC__)#error please add daylight savings offset here! result = Number(_timezone / 60 - (_daylight ? 60 : 0));# else result = Number(( timezone / 60 - ( daylight ? 60 : 0 )));# endif#endif break; case SetTime: milli = args[0].round(); result = Number(milli); thisObj.setInternalValue(result); break; case SetMilliSeconds: ms = args[0].toInt32(); break; case SetSeconds: t->tm_sec = args[0].toInt32(); break; case SetMinutes: t->tm_min = args[0].toInt32(); break; case SetHours: t->tm_hour = args[0].toInt32(); break; case SetDate: t->tm_mday = args[0].toInt32(); break; case SetMonth: t->tm_mon = args[0].toInt32(); break; case SetFullYear: t->tm_year = args[0].toInt32() - 1900; break; case SetYear: t->tm_year = args[0].toInt32() >= 1900 ? args[0].toInt32() - 1900 : args[0].toInt32(); break; } if (id == SetYear || id == SetMilliSeconds || id == SetSeconds || id == SetMinutes || id == SetHours || id == SetDate || id == SetMonth || id == SetFullYear ) { result = Number(mktime(t) * 1000.0 + ms); thisObj.setInternalValue(result); } return Completion(ReturnValue, result);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?