?? nativedate.java
字號:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1997-1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Norris Boyd * Mike McCabe * * Alternatively, the contents of this file may be used under the * terms of the GNU Public License (the "GPL"), in which case the * provisions of the GPL are applicable instead of those above. * If you wish to allow use of your version of this file only * under the terms of the GPL and not to allow others to use your * version of this file under the NPL, indicate your decision by * deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete * the provisions above, a recipient may use your version of this * file under either the NPL or the GPL. */package org.mozilla.javascript;import java.util.Date;import java.text.DateFormat;/** * This class implements the Date native object. * See ECMA 15.9. * @author Mike McCabe */final class NativeDate extends IdScriptableObject{ static final long serialVersionUID = -8307438915861678966L; private static final Object DATE_TAG = new Object(); private static final String js_NaN_date_str = "Invalid Date"; static void init(Scriptable scope, boolean sealed) { NativeDate obj = new NativeDate(); // Set the value of the prototype Date to NaN ('invalid date'); obj.date = ScriptRuntime.NaN; obj.exportAsJSClass(MAX_PROTOTYPE_ID, scope, sealed); } private NativeDate() { if (thisTimeZone == null) { // j.u.TimeZone is synchronized, so setting class statics from it // should be OK. thisTimeZone = java.util.TimeZone.getDefault(); LocalTZA = thisTimeZone.getRawOffset(); } } public String getClassName() { return "Date"; } public Object getDefaultValue(Class typeHint) { if (typeHint == null) typeHint = ScriptRuntime.StringClass; return super.getDefaultValue(typeHint); } double getJSTimeValue() { return date; } protected void fillConstructorProperties(IdFunctionObject ctor) { addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_now, "now", 0); addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_parse, "parse", 1); addIdFunctionProperty(ctor, DATE_TAG, ConstructorId_UTC, "UTC", 1); super.fillConstructorProperties(ctor); } protected void initPrototypeId(int id) { String s; int arity; switch (id) { case Id_constructor: arity=1; s="constructor"; break; case Id_toString: arity=0; s="toString"; break; case Id_toTimeString: arity=0; s="toTimeString"; break; case Id_toDateString: arity=0; s="toDateString"; break; case Id_toLocaleString: arity=0; s="toLocaleString"; break; case Id_toLocaleTimeString: arity=0; s="toLocaleTimeString"; break; case Id_toLocaleDateString: arity=0; s="toLocaleDateString"; break; case Id_toUTCString: arity=0; s="toUTCString"; break; case Id_toSource: arity=0; s="toSource"; break; case Id_valueOf: arity=0; s="valueOf"; break; case Id_getTime: arity=0; s="getTime"; break; case Id_getYear: arity=0; s="getYear"; break; case Id_getFullYear: arity=0; s="getFullYear"; break; case Id_getUTCFullYear: arity=0; s="getUTCFullYear"; break; case Id_getMonth: arity=0; s="getMonth"; break; case Id_getUTCMonth: arity=0; s="getUTCMonth"; break; case Id_getDate: arity=0; s="getDate"; break; case Id_getUTCDate: arity=0; s="getUTCDate"; break; case Id_getDay: arity=0; s="getDay"; break; case Id_getUTCDay: arity=0; s="getUTCDay"; break; case Id_getHours: arity=0; s="getHours"; break; case Id_getUTCHours: arity=0; s="getUTCHours"; break; case Id_getMinutes: arity=0; s="getMinutes"; break; case Id_getUTCMinutes: arity=0; s="getUTCMinutes"; break; case Id_getSeconds: arity=0; s="getSeconds"; break; case Id_getUTCSeconds: arity=0; s="getUTCSeconds"; break; case Id_getMilliseconds: arity=0; s="getMilliseconds"; break; case Id_getUTCMilliseconds: arity=0; s="getUTCMilliseconds"; break; case Id_getTimezoneOffset: arity=0; s="getTimezoneOffset"; break; case Id_setTime: arity=1; s="setTime"; break; case Id_setMilliseconds: arity=1; s="setMilliseconds"; break; case Id_setUTCMilliseconds: arity=1; s="setUTCMilliseconds"; break; case Id_setSeconds: arity=2; s="setSeconds"; break; case Id_setUTCSeconds: arity=2; s="setUTCSeconds"; break; case Id_setMinutes: arity=3; s="setMinutes"; break; case Id_setUTCMinutes: arity=3; s="setUTCMinutes"; break; case Id_setHours: arity=4; s="setHours"; break; case Id_setUTCHours: arity=4; s="setUTCHours"; break; case Id_setDate: arity=1; s="setDate"; break; case Id_setUTCDate: arity=1; s="setUTCDate"; break; case Id_setMonth: arity=2; s="setMonth"; break; case Id_setUTCMonth: arity=2; s="setUTCMonth"; break; case Id_setFullYear: arity=3; s="setFullYear"; break; case Id_setUTCFullYear: arity=3; s="setUTCFullYear"; break; case Id_setYear: arity=1; s="setYear"; break; default: throw new IllegalArgumentException(String.valueOf(id)); } initPrototypeMethod(DATE_TAG, id, s, arity); } public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { if (!f.hasTag(DATE_TAG)) { return super.execIdCall(f, cx, scope, thisObj, args); } int id = f.methodId(); switch (id) { case ConstructorId_now: return ScriptRuntime.wrapNumber(now()); case ConstructorId_parse: { String dataStr = ScriptRuntime.toString(args, 0); return ScriptRuntime.wrapNumber(date_parseString(dataStr)); } case ConstructorId_UTC: return ScriptRuntime.wrapNumber(jsStaticFunction_UTC(args)); case Id_constructor: { // if called as a function, just return a string // representing the current time. if (thisObj != null) return date_format(now(), Id_toString); return jsConstructor(args); } } // The rest of Date.prototype methods require thisObj to be Date if (!(thisObj instanceof NativeDate)) throw incompatibleCallError(f); NativeDate realThis = (NativeDate)thisObj; double t = realThis.date; switch (id) { case Id_toString: case Id_toTimeString: case Id_toDateString: if (t == t) { return date_format(t, id); } return js_NaN_date_str; case Id_toLocaleString: case Id_toLocaleTimeString: case Id_toLocaleDateString: if (t == t) { return toLocale_helper(t, id); } return js_NaN_date_str; case Id_toUTCString: if (t == t) { return js_toUTCString(t); } return js_NaN_date_str; case Id_toSource: return "(new Date("+ScriptRuntime.toString(t)+"))"; case Id_valueOf: case Id_getTime: return ScriptRuntime.wrapNumber(t); case Id_getYear: case Id_getFullYear: case Id_getUTCFullYear: if (t == t) { if (id != Id_getUTCFullYear) t = LocalTime(t); t = YearFromTime(t); if (id == Id_getYear) { if (cx.hasFeature(Context.FEATURE_NON_ECMA_GET_YEAR)) { if (1900 <= t && t < 2000) { t -= 1900; } } else { t -= 1900; } } } return ScriptRuntime.wrapNumber(t); case Id_getMonth: case Id_getUTCMonth: if (t == t) { if (id == Id_getMonth) t = LocalTime(t); t = MonthFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getDate: case Id_getUTCDate: if (t == t) { if (id == Id_getDate) t = LocalTime(t); t = DateFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getDay: case Id_getUTCDay: if (t == t) { if (id == Id_getDay) t = LocalTime(t); t = WeekDay(t); } return ScriptRuntime.wrapNumber(t); case Id_getHours: case Id_getUTCHours: if (t == t) { if (id == Id_getHours) t = LocalTime(t); t = HourFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getMinutes: case Id_getUTCMinutes: if (t == t) { if (id == Id_getMinutes) t = LocalTime(t); t = MinFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getSeconds: case Id_getUTCSeconds: if (t == t) { if (id == Id_getSeconds) t = LocalTime(t); t = SecFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getMilliseconds: case Id_getUTCMilliseconds: if (t == t) { if (id == Id_getMilliseconds) t = LocalTime(t); t = msFromTime(t); } return ScriptRuntime.wrapNumber(t); case Id_getTimezoneOffset: if (t == t) { t = (t - LocalTime(t)) / msPerMinute; } return ScriptRuntime.wrapNumber(t); case Id_setTime: t = TimeClip(ScriptRuntime.toNumber(args, 0)); realThis.date = t; return ScriptRuntime.wrapNumber(t); case Id_setMilliseconds: case Id_setUTCMilliseconds: case Id_setSeconds: case Id_setUTCSeconds: case Id_setMinutes: case Id_setUTCMinutes: case Id_setHours: case Id_setUTCHours: t = makeTime(t, args, id); realThis.date = t; return ScriptRuntime.wrapNumber(t); case Id_setDate: case Id_setUTCDate: case Id_setMonth: case Id_setUTCMonth: case Id_setFullYear: case Id_setUTCFullYear: t = makeDate(t, args, id); realThis.date = t; return ScriptRuntime.wrapNumber(t); case Id_setYear: { double year = ScriptRuntime.toNumber(args, 0); if (year != year || Double.isInfinite(year)) { t = ScriptRuntime.NaN; } else { if (t != t) { t = 0; } else { t = LocalTime(t); } if (year >= 0 && year <= 99) year += 1900; double day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); t = MakeDate(day, TimeWithinDay(t)); t = internalUTC(t); t = TimeClip(t); } } realThis.date = t; return ScriptRuntime.wrapNumber(t); default: throw new IllegalArgumentException(String.valueOf(id)); } } /* ECMA helper functions */ private static final double HalfTimeDomain = 8.64e15; private static final double HoursPerDay = 24.0; private static final double MinutesPerHour = 60.0; private static final double SecondsPerMinute = 60.0; private static final double msPerSecond = 1000.0; private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour); private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute); private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute); private static final double msPerDay = (SecondsPerDay * msPerSecond); private static final double msPerHour = (SecondsPerHour * msPerSecond); private static final double msPerMinute = (SecondsPerMinute * msPerSecond); private static double Day(double t) { return Math.floor(t / msPerDay); } private static double TimeWithinDay(double t) { double result; result = t % msPerDay; if (result < 0) result += msPerDay; return result; } private static boolean IsLeapYear(int year) { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } /* math here has to be f.p, because we need * floor((1968 - 1969) / 4) == -1 */ private static double DayFromYear(double y) { return ((365 * ((y)-1970) + Math.floor(((y)-1969)/4.0) - Math.floor(((y)-1901)/100.0) + Math.floor(((y)-1601)/400.0))); } private static double TimeFromYear(double y) { return DayFromYear(y) * msPerDay;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -