1/* 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 18 * USA 19 * 20 */ 21 22#include "config.h" 23#include "DateConstructor.h" 24 25#include "DateConversion.h" 26#include "DateInstance.h" 27#include "DatePrototype.h" 28#include "JSFunction.h" 29#include "JSGlobalObject.h" 30#include "JSString.h" 31#include "JSStringBuilder.h" 32#include "ObjectPrototype.h" 33#include "PrototypeFunction.h" 34#include <math.h> 35#include <time.h> 36#include <wtf/DateMath.h> 37#include <wtf/MathExtras.h> 38 39#if OS(WINCE) && !PLATFORM(QT) 40extern "C" time_t time(time_t* timer); // Provided by libce. 41#endif 42 43#if HAVE(SYS_TIME_H) 44#include <sys/time.h> 45#endif 46 47#if HAVE(SYS_TIMEB_H) 48#include <sys/timeb.h> 49#endif 50 51using namespace WTF; 52 53namespace JSC { 54 55ASSERT_CLASS_FITS_IN_CELL(DateConstructor); 56 57static JSValue JSC_HOST_CALL dateParse(ExecState*, JSObject*, JSValue, const ArgList&); 58static JSValue JSC_HOST_CALL dateNow(ExecState*, JSObject*, JSValue, const ArgList&); 59static JSValue JSC_HOST_CALL dateUTC(ExecState*, JSObject*, JSValue, const ArgList&); 60 61DateConstructor::DateConstructor(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure, DatePrototype* datePrototype) 62 : InternalFunction(&exec->globalData(), structure, Identifier(exec, datePrototype->classInfo()->className)) 63{ 64 putDirectWithoutTransition(exec->propertyNames().prototype, datePrototype, DontEnum|DontDelete|ReadOnly); 65 66 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 1, exec->propertyNames().parse, dateParse), DontEnum); 67 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 7, exec->propertyNames().UTC, dateUTC), DontEnum); 68 putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().now, dateNow), DontEnum); 69 70 putDirectWithoutTransition(exec->propertyNames().length, jsNumber(exec, 7), ReadOnly | DontEnum | DontDelete); 71} 72 73// ECMA 15.9.3 74JSObject* constructDate(ExecState* exec, const ArgList& args) 75{ 76 int numArgs = args.size(); 77 78 double value; 79 80 if (numArgs == 0) // new Date() ECMA 15.9.3.3 81 value = jsCurrentTime(); 82 else if (numArgs == 1) { 83 if (args.at(0).inherits(&DateInstance::info)) 84 value = asDateInstance(args.at(0))->internalNumber(); 85 else { 86 JSValue primitive = args.at(0).toPrimitive(exec); 87 if (primitive.isString()) 88 value = parseDate(exec, primitive.getString(exec)); 89 else 90 value = primitive.toNumber(exec); 91 } 92 } else { 93 if (isnan(args.at(0).toNumber(exec)) 94 || isnan(args.at(1).toNumber(exec)) 95 || (numArgs >= 3 && isnan(args.at(2).toNumber(exec))) 96 || (numArgs >= 4 && isnan(args.at(3).toNumber(exec))) 97 || (numArgs >= 5 && isnan(args.at(4).toNumber(exec))) 98 || (numArgs >= 6 && isnan(args.at(5).toNumber(exec))) 99 || (numArgs >= 7 && isnan(args.at(6).toNumber(exec)))) 100 value = NaN; 101 else { 102 GregorianDateTime t; 103 int year = args.at(0).toInt32(exec); 104 t.year = (year >= 0 && year <= 99) ? year : year - 1900; 105 t.month = args.at(1).toInt32(exec); 106 t.monthDay = (numArgs >= 3) ? args.at(2).toInt32(exec) : 1; 107 t.hour = args.at(3).toInt32(exec); 108 t.minute = args.at(4).toInt32(exec); 109 t.second = args.at(5).toInt32(exec); 110 t.isDST = -1; 111 double ms = (numArgs >= 7) ? args.at(6).toNumber(exec) : 0; 112 value = gregorianDateTimeToMS(exec, t, ms, false); 113 } 114 } 115 116 return new (exec) DateInstance(exec, value); 117} 118 119static JSObject* constructWithDateConstructor(ExecState* exec, JSObject*, const ArgList& args) 120{ 121 return constructDate(exec, args); 122} 123 124ConstructType DateConstructor::getConstructData(ConstructData& constructData) 125{ 126 constructData.native.function = constructWithDateConstructor; 127 return ConstructTypeHost; 128} 129 130// ECMA 15.9.2 131static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const ArgList&) 132{ 133 time_t localTime = time(0); 134 tm localTM; 135 getLocalTime(&localTime, &localTM); 136 GregorianDateTime ts(exec, localTM); 137 DateConversionBuffer date; 138 DateConversionBuffer time; 139 formatDate(ts, date); 140 formatTime(ts, time); 141 return jsMakeNontrivialString(exec, date, " ", time); 142} 143 144CallType DateConstructor::getCallData(CallData& callData) 145{ 146 callData.native.function = callDate; 147 return CallTypeHost; 148} 149 150static JSValue JSC_HOST_CALL dateParse(ExecState* exec, JSObject*, JSValue, const ArgList& args) 151{ 152 return jsNumber(exec, parseDate(exec, args.at(0).toString(exec))); 153} 154 155static JSValue JSC_HOST_CALL dateNow(ExecState* exec, JSObject*, JSValue, const ArgList&) 156{ 157 return jsNumber(exec, jsCurrentTime()); 158} 159 160static JSValue JSC_HOST_CALL dateUTC(ExecState* exec, JSObject*, JSValue, const ArgList& args) 161{ 162 int n = args.size(); 163 if (isnan(args.at(0).toNumber(exec)) 164 || isnan(args.at(1).toNumber(exec)) 165 || (n >= 3 && isnan(args.at(2).toNumber(exec))) 166 || (n >= 4 && isnan(args.at(3).toNumber(exec))) 167 || (n >= 5 && isnan(args.at(4).toNumber(exec))) 168 || (n >= 6 && isnan(args.at(5).toNumber(exec))) 169 || (n >= 7 && isnan(args.at(6).toNumber(exec)))) 170 return jsNaN(exec); 171 172 GregorianDateTime t; 173 int year = args.at(0).toInt32(exec); 174 t.year = (year >= 0 && year <= 99) ? year : year - 1900; 175 t.month = args.at(1).toInt32(exec); 176 t.monthDay = (n >= 3) ? args.at(2).toInt32(exec) : 1; 177 t.hour = args.at(3).toInt32(exec); 178 t.minute = args.at(4).toInt32(exec); 179 t.second = args.at(5).toInt32(exec); 180 double ms = (n >= 7) ? args.at(6).toNumber(exec) : 0; 181 return jsNumber(exec, timeClip(gregorianDateTimeToMS(exec, t, ms, true))); 182} 183 184} // namespace JSC 185