1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
\r
3 * The contents of this file are subject to the Netscape Public
\r
4 * License Version 1.1 (the "License"); you may not use this file
\r
5 * except in compliance with the License. You may obtain a copy of
\r
6 * the License at http://www.mozilla.org/NPL/
\r
8 * Software distributed under the License is distributed on an "AS
\r
9 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
\r
10 * implied. See the License for the specific language governing
\r
11 * rights and limitations under the License.
\r
13 * The Original Code is Rhino code, released
\r
16 * The Initial Developer of the Original Code is Netscape
\r
17 * Communications Corporation. Portions created by Netscape are
\r
18 * Copyright (C) 1997-1999 Netscape Communications Corporation. All
\r
25 * Alternatively, the contents of this file may be used under the
\r
26 * terms of the GNU Public License (the "GPL"), in which case the
\r
27 * provisions of the GPL are applicable instead of those above.
\r
28 * If you wish to allow use of your version of this file only
\r
29 * under the terms of the GPL and not to allow others to use your
\r
30 * version of this file under the NPL, indicate your decision by
\r
31 * deleting the provisions above and replace them with the notice
\r
32 * and other provisions required by the GPL. If you do not delete
\r
33 * the provisions above, a recipient may use your version of this
\r
34 * file under either the NPL or the GPL.
\r
37 package org.mozilla.javascript;
\r
39 import java.util.Date;
\r
40 import java.util.TimeZone;
\r
41 import java.util.Locale;
\r
42 import java.text.NumberFormat;
\r
43 import java.text.DateFormat;
\r
44 import java.text.SimpleDateFormat;
\r
47 * This class implements the Date native object.
\r
49 * @author Mike McCabe
\r
51 public class NativeDate extends IdScriptable {
\r
53 public static void init(Context cx, Scriptable scope, boolean sealed) {
\r
54 NativeDate obj = new NativeDate();
\r
55 obj.prototypeFlag = true;
\r
57 // Set the value of the prototype Date to NaN ('invalid date');
\r
58 obj.date = ScriptRuntime.NaN;
\r
60 obj.addAsPrototype(MAX_PROTOTYPE_ID, cx, scope, sealed);
\r
63 public NativeDate() {
\r
64 if (thisTimeZone == null) {
\r
65 // j.u.TimeZone is synchronized, so setting class statics from it
\r
67 thisTimeZone = java.util.TimeZone.getDefault();
\r
68 LocalTZA = thisTimeZone.getRawOffset();
\r
72 public String getClassName() {
\r
76 public Object getDefaultValue(Class typeHint) {
\r
77 if (typeHint == null)
\r
78 typeHint = ScriptRuntime.StringClass;
\r
79 return super.getDefaultValue(typeHint);
\r
82 protected void fillConstructorProperties
\r
83 (Context cx, IdFunction ctor, boolean sealed)
\r
85 addIdFunctionProperty(ctor, ConstructorId_UTC, sealed);
\r
86 addIdFunctionProperty(ctor, ConstructorId_parse, sealed);
\r
87 super.fillConstructorProperties(cx, ctor, sealed);
\r
90 public int methodArity(int methodId) {
\r
91 if (prototypeFlag) {
\r
93 case ConstructorId_UTC: return 1;
\r
94 case ConstructorId_parse: return 1;
\r
95 case Id_constructor: return 1;
\r
96 case Id_toString: return 0;
\r
97 case Id_toTimeString: return 0;
\r
98 case Id_toDateString: return 0;
\r
99 case Id_toLocaleString: return 0;
\r
100 case Id_toLocaleTimeString: return 0;
\r
101 case Id_toLocaleDateString: return 0;
\r
102 case Id_toUTCString: return 0;
\r
103 case Id_valueOf: return 0;
\r
104 case Id_getTime: return 0;
\r
105 case Id_getYear: return 0;
\r
106 case Id_getFullYear: return 0;
\r
107 case Id_getUTCFullYear: return 0;
\r
108 case Id_getMonth: return 0;
\r
109 case Id_getUTCMonth: return 0;
\r
110 case Id_getDate: return 0;
\r
111 case Id_getUTCDate: return 0;
\r
112 case Id_getDay: return 0;
\r
113 case Id_getUTCDay: return 0;
\r
114 case Id_getHours: return 0;
\r
115 case Id_getUTCHours: return 0;
\r
116 case Id_getMinutes: return 0;
\r
117 case Id_getUTCMinutes: return 0;
\r
118 case Id_getSeconds: return 0;
\r
119 case Id_getUTCSeconds: return 0;
\r
120 case Id_getMilliseconds: return 0;
\r
121 case Id_getUTCMilliseconds: return 0;
\r
122 case Id_getTimezoneOffset: return 0;
\r
123 case Id_setTime: return 1;
\r
124 case Id_setMilliseconds: return 1;
\r
125 case Id_setUTCMilliseconds: return 1;
\r
126 case Id_setSeconds: return 2;
\r
127 case Id_setUTCSeconds: return 2;
\r
128 case Id_setMinutes: return 3;
\r
129 case Id_setUTCMinutes: return 3;
\r
130 case Id_setHours: return 4;
\r
131 case Id_setUTCHours: return 4;
\r
132 case Id_setDate: return 1;
\r
133 case Id_setUTCDate: return 1;
\r
134 case Id_setMonth: return 2;
\r
135 case Id_setUTCMonth: return 2;
\r
136 case Id_setFullYear: return 3;
\r
137 case Id_setUTCFullYear: return 3;
\r
138 case Id_setYear: return 1;
\r
141 return super.methodArity(methodId);
\r
144 public Object execMethod
\r
145 (int methodId, IdFunction f,
\r
146 Context cx, Scriptable scope, Scriptable thisObj, Object[] args)
\r
147 throws JavaScriptException
\r
149 if (prototypeFlag) {
\r
150 switch (methodId) {
\r
151 case ConstructorId_UTC:
\r
152 return wrap_double(jsStaticFunction_UTC(args));
\r
154 case ConstructorId_parse:
\r
155 return wrap_double(jsStaticFunction_parse
\r
156 (ScriptRuntime.toString(args, 0)));
\r
158 case Id_constructor:
\r
159 return jsConstructor(args, thisObj == null);
\r
161 case Id_toString: {
\r
162 double t = realThis(thisObj, f, true).date;
\r
163 return date_format(t, FORMATSPEC_FULL);
\r
166 case Id_toTimeString: {
\r
167 double t = realThis(thisObj, f, true).date;
\r
168 return date_format(t, FORMATSPEC_TIME);
\r
171 case Id_toDateString: {
\r
172 double t = realThis(thisObj, f, true).date;
\r
173 return date_format(t, FORMATSPEC_DATE);
\r
176 case Id_toLocaleString: {
\r
177 double t = realThis(thisObj, f, true).date;
\r
178 return jsFunction_toLocaleString(t);
\r
181 case Id_toLocaleTimeString: {
\r
182 double t = realThis(thisObj, f, true).date;
\r
183 return jsFunction_toLocaleTimeString(t);
\r
186 case Id_toLocaleDateString: {
\r
187 double t = realThis(thisObj, f, true).date;
\r
188 return jsFunction_toLocaleDateString(t);
\r
191 case Id_toUTCString: {
\r
192 double t = realThis(thisObj, f, true).date;
\r
193 if (t == t) { return jsFunction_toUTCString(t); }
\r
194 return jsFunction_NaN_date_str;
\r
198 return wrap_double(realThis(thisObj, f, true).date);
\r
201 return wrap_double(realThis(thisObj, f, true).date);
\r
204 double t = realThis(thisObj, f, true).date;
\r
205 if (t == t) { t = jsFunction_getYear(cx, t); }
\r
206 return wrap_double(t);
\r
209 case Id_getFullYear: {
\r
210 double t = realThis(thisObj, f, true).date;
\r
211 if (t == t) { t = YearFromTime(LocalTime(t)); }
\r
212 return wrap_double(t);
\r
215 case Id_getUTCFullYear: {
\r
216 double t = realThis(thisObj, f, true).date;
\r
217 if (t == t) { t = YearFromTime(t); }
\r
218 return wrap_double(t);
\r
221 case Id_getMonth: {
\r
222 double t = realThis(thisObj, f, true).date;
\r
223 if (t == t) { t = MonthFromTime(LocalTime(t)); }
\r
224 return wrap_double(t);
\r
227 case Id_getUTCMonth: {
\r
228 double t = realThis(thisObj, f, true).date;
\r
229 if (t == t) { t = MonthFromTime(t); }
\r
230 return wrap_double(t);
\r
234 double t = realThis(thisObj, f, true).date;
\r
235 if (t == t) { t = DateFromTime(LocalTime(t)); }
\r
236 return wrap_double(t);
\r
239 case Id_getUTCDate: {
\r
240 double t = realThis(thisObj, f, true).date;
\r
241 if (t == t) { t = DateFromTime(t); }
\r
242 return wrap_double(t);
\r
246 double t = realThis(thisObj, f, true).date;
\r
247 if (t == t) { t = WeekDay(LocalTime(t)); }
\r
248 return wrap_double(t);
\r
251 case Id_getUTCDay: {
\r
252 double t = realThis(thisObj, f, true).date;
\r
253 if (t == t) { t = WeekDay(t); }
\r
254 return wrap_double(t);
\r
257 case Id_getHours: {
\r
258 double t = realThis(thisObj, f, true).date;
\r
259 if (t == t) { t = HourFromTime(LocalTime(t)); }
\r
260 return wrap_double(t);
\r
263 case Id_getUTCHours: {
\r
264 double t = realThis(thisObj, f, true).date;
\r
265 if (t == t) { t = HourFromTime(t); }
\r
266 return wrap_double(t);
\r
269 case Id_getMinutes: {
\r
270 double t = realThis(thisObj, f, true).date;
\r
271 if (t == t) { t = MinFromTime(LocalTime(t)); }
\r
272 return wrap_double(t);
\r
275 case Id_getUTCMinutes: {
\r
276 double t = realThis(thisObj, f, true).date;
\r
277 if (t == t) { t = MinFromTime(t); }
\r
278 return wrap_double(t);
\r
281 case Id_getSeconds: {
\r
282 double t = realThis(thisObj, f, true).date;
\r
283 if (t == t) { t = SecFromTime(LocalTime(t)); }
\r
284 return wrap_double(t);
\r
287 case Id_getUTCSeconds: {
\r
288 double t = realThis(thisObj, f, true).date;
\r
289 if (t == t) { t = SecFromTime(t); }
\r
290 return wrap_double(t);
\r
293 case Id_getMilliseconds: {
\r
294 double t = realThis(thisObj, f, true).date;
\r
295 if (t == t) { t = msFromTime(LocalTime(t)); }
\r
296 return wrap_double(t);
\r
299 case Id_getUTCMilliseconds: {
\r
300 double t = realThis(thisObj, f, true).date;
\r
301 if (t == t) { t = msFromTime(t); }
\r
302 return wrap_double(t);
\r
305 case Id_getTimezoneOffset: {
\r
306 double t = realThis(thisObj, f, true).date;
\r
307 if (t == t) { t = jsFunction_getTimezoneOffset(t); }
\r
308 return wrap_double(t);
\r
312 return wrap_double(realThis(thisObj, f, true).
\r
313 jsFunction_setTime(ScriptRuntime.toNumber(args, 0)));
\r
315 case Id_setMilliseconds:
\r
316 return wrap_double(realThis(thisObj, f, false).
\r
317 makeTime(args, 1, true));
\r
319 case Id_setUTCMilliseconds:
\r
320 return wrap_double(realThis(thisObj, f, false).
\r
321 makeTime(args, 1, false));
\r
323 case Id_setSeconds:
\r
324 return wrap_double(realThis(thisObj, f, false).
\r
325 makeTime(args, 2, true));
\r
327 case Id_setUTCSeconds:
\r
328 return wrap_double(realThis(thisObj, f, false).
\r
329 makeTime(args, 2, false));
\r
331 case Id_setMinutes:
\r
332 return wrap_double(realThis(thisObj, f, false).
\r
333 makeTime(args, 3, true));
\r
335 case Id_setUTCMinutes:
\r
336 return wrap_double(realThis(thisObj, f, false).
\r
337 makeTime(args, 3, false));
\r
340 return wrap_double(realThis(thisObj, f, false).
\r
341 makeTime(args, 4, true));
\r
343 case Id_setUTCHours:
\r
344 return wrap_double(realThis(thisObj, f, false).
\r
345 makeTime(args, 4, false));
\r
348 return wrap_double(realThis(thisObj, f, false).
\r
349 makeDate(args, 1, true));
\r
351 case Id_setUTCDate:
\r
352 return wrap_double(realThis(thisObj, f, false).
\r
353 makeDate(args, 1, false));
\r
356 return wrap_double(realThis(thisObj, f, false).
\r
357 makeDate(args, 2, true));
\r
359 case Id_setUTCMonth:
\r
360 return wrap_double(realThis(thisObj, f, false).
\r
361 makeDate(args, 2, false));
\r
363 case Id_setFullYear:
\r
364 return wrap_double(realThis(thisObj, f, false).
\r
365 makeDate(args, 3, true));
\r
367 case Id_setUTCFullYear:
\r
368 return wrap_double(realThis(thisObj, f, false).
\r
369 makeDate(args, 3, false));
\r
372 return wrap_double(realThis(thisObj, f, false).
\r
373 jsFunction_setYear(ScriptRuntime.toNumber(args, 0)));
\r
377 return super.execMethod(methodId, f, cx, scope, thisObj, args);
\r
380 private NativeDate realThis(Scriptable thisObj, IdFunction f,
\r
383 while (!(thisObj instanceof NativeDate)) {
\r
384 thisObj = nextInstanceCheck(thisObj, f, readOnly);
\r
386 return (NativeDate)thisObj;
\r
389 /* ECMA helper functions */
\r
391 private static final double HalfTimeDomain = 8.64e15;
\r
392 private static final double HoursPerDay = 24.0;
\r
393 private static final double MinutesPerHour = 60.0;
\r
394 private static final double SecondsPerMinute = 60.0;
\r
395 private static final double msPerSecond = 1000.0;
\r
396 private static final double MinutesPerDay = (HoursPerDay * MinutesPerHour);
\r
397 private static final double SecondsPerDay = (MinutesPerDay * SecondsPerMinute);
\r
398 private static final double SecondsPerHour = (MinutesPerHour * SecondsPerMinute);
\r
399 private static final double msPerDay = (SecondsPerDay * msPerSecond);
\r
400 private static final double msPerHour = (SecondsPerHour * msPerSecond);
\r
401 private static final double msPerMinute = (SecondsPerMinute * msPerSecond);
\r
403 private static double Day(double t) {
\r
404 return Math.floor(t / msPerDay);
\r
407 private static double TimeWithinDay(double t) {
\r
409 result = t % msPerDay;
\r
411 result += msPerDay;
\r
415 private static int DaysInYear(int y) {
\r
416 if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
\r
423 /* math here has to be f.p, because we need
\r
424 * floor((1968 - 1969) / 4) == -1
\r
426 private static double DayFromYear(double y) {
\r
427 return ((365 * ((y)-1970) + Math.floor(((y)-1969)/4.0)
\r
428 - Math.floor(((y)-1901)/100.0) + Math.floor(((y)-1601)/400.0)));
\r
431 private static double TimeFromYear(double y) {
\r
432 return DayFromYear(y) * msPerDay;
\r
435 private static int YearFromTime(double t) {
\r
436 int lo = (int) Math.floor((t / msPerDay) / 366) + 1970;
\r
437 int hi = (int) Math.floor((t / msPerDay) / 365) + 1970;
\r
440 /* above doesn't work for negative dates... */
\r
447 /* Use a simple binary search algorithm to find the right
\r
448 year. This seems like brute force... but the computation
\r
449 of hi and lo years above lands within one year of the
\r
450 correct answer for years within a thousand years of
\r
451 1970; the loop below only requires six iterations
\r
452 for year 270000. */
\r
454 mid = (hi + lo) / 2;
\r
455 if (TimeFromYear(mid) > t) {
\r
458 if (TimeFromYear(mid) <= t) {
\r
459 int temp = mid + 1;
\r
460 if (TimeFromYear(temp) > t) {
\r
470 private static boolean InLeapYear(double t) {
\r
471 return DaysInYear(YearFromTime(t)) == 366;
\r
474 private static int DayWithinYear(double t) {
\r
475 int year = YearFromTime(t);
\r
476 return (int) (Day(t) - DayFromYear(year));
\r
479 * The following array contains the day of year for the first day of
\r
480 * each month, where index 0 is January, and day 0 is January 1.
\r
483 private static double DayFromMonth(int m, boolean leap) {
\r
486 if (m >= 7) { day += m / 2 - 1; }
\r
487 else if (m >= 2) { day += (m - 1) / 2 - 1; }
\r
490 if (leap && m >= 2) { ++day; }
\r
495 private static int MonthFromTime(double t) {
\r
498 d = DayWithinYear(t);
\r
500 if (d < (step = 31))
\r
503 // Originally coded as step += (InLeapYear(t) ? 29 : 28);
\r
504 // but some jits always returned 28!
\r
512 if (d < (step += 31))
\r
514 if (d < (step += 30))
\r
516 if (d < (step += 31))
\r
518 if (d < (step += 30))
\r
520 if (d < (step += 31))
\r
522 if (d < (step += 31))
\r
524 if (d < (step += 30))
\r
526 if (d < (step += 31))
\r
528 if (d < (step += 30))
\r
533 private static int DateFromTime(double t) {
\r
536 d = DayWithinYear(t);
\r
537 if (d <= (next = 30))
\r
541 // Originally coded as next += (InLeapYear(t) ? 29 : 28);
\r
542 // but some jits always returned 28!
\r
551 if (d <= (next += 31))
\r
554 if (d <= (next += 30))
\r
557 if (d <= (next += 31))
\r
560 if (d <= (next += 30))
\r
563 if (d <= (next += 31))
\r
566 if (d <= (next += 31))
\r
569 if (d <= (next += 30))
\r
572 if (d <= (next += 31))
\r
575 if (d <= (next += 30))
\r
582 private static int WeekDay(double t) {
\r
584 result = Day(t) + 4;
\r
585 result = result % 7;
\r
588 return (int) result;
\r
591 private static double Now() {
\r
592 return (double) System.currentTimeMillis();
\r
595 /* Should be possible to determine the need for this dynamically
\r
596 * if we go with the workaround... I'm not using it now, because I
\r
597 * can't think of any clean way to make toLocaleString() and the
\r
598 * time zone (comment) in toString match the generated string
\r
599 * values. Currently it's wrong-but-consistent in all but the
\r
600 * most recent betas of the JRE - seems to work in 1.1.7.
\r
602 private final static boolean TZO_WORKAROUND = false;
\r
603 private static double DaylightSavingTA(double t) {
\r
604 if (!TZO_WORKAROUND) {
\r
605 Date date = new Date((long) t);
\r
606 if (thisTimeZone.inDaylightTime(date))
\r
611 /* Use getOffset if inDaylightTime() is broken, because it
\r
612 * seems to work acceptably. We don't switch over to it
\r
613 * entirely, because it requires (expensive) exploded date arguments,
\r
614 * and the api makes it impossible to handle dst
\r
615 * changeovers cleanly.
\r
618 // Hardcode the assumption that the changeover always
\r
619 // happens at 2:00 AM:
\r
620 t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0);
\r
622 int year = YearFromTime(t);
\r
623 double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0,
\r
628 (int)TimeWithinDay(t));
\r
630 if ((offset - LocalTZA) != 0)
\r
634 // return offset - LocalTZA;
\r
638 private static double LocalTime(double t) {
\r
639 return t + LocalTZA + DaylightSavingTA(t);
\r
642 public static double internalUTC(double t) {
\r
643 return t - LocalTZA - DaylightSavingTA(t - LocalTZA);
\r
646 private static int HourFromTime(double t) {
\r
648 result = Math.floor(t / msPerHour) % HoursPerDay;
\r
650 result += HoursPerDay;
\r
651 return (int) result;
\r
654 private static int MinFromTime(double t) {
\r
656 result = Math.floor(t / msPerMinute) % MinutesPerHour;
\r
658 result += MinutesPerHour;
\r
659 return (int) result;
\r
662 private static int SecFromTime(double t) {
\r
664 result = Math.floor(t / msPerSecond) % SecondsPerMinute;
\r
666 result += SecondsPerMinute;
\r
667 return (int) result;
\r
670 private static int msFromTime(double t) {
\r
672 result = t % msPerSecond;
\r
674 result += msPerSecond;
\r
675 return (int) result;
\r
678 private static double MakeTime(double hour, double min,
\r
679 double sec, double ms)
\r
681 return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec)
\r
682 * msPerSecond + ms;
\r
685 private static double MakeDay(double year, double month, double date) {
\r
691 year += Math.floor(month / 12);
\r
693 month = month % 12;
\r
697 leap = (DaysInYear((int) year) == 366);
\r
699 yearday = Math.floor(TimeFromYear(year) / msPerDay);
\r
700 monthday = DayFromMonth((int) month, leap);
\r
708 private static double MakeDate(double day, double time) {
\r
709 return day * msPerDay + time;
\r
712 private static double TimeClip(double d) {
\r
714 d == Double.POSITIVE_INFINITY ||
\r
715 d == Double.NEGATIVE_INFINITY ||
\r
716 Math.abs(d) > HalfTimeDomain)
\r
718 return ScriptRuntime.NaN;
\r
721 return Math.floor(d + 0.);
\r
723 return Math.ceil(d + 0.);
\r
726 /* end of ECMA helper functions */
\r
728 /* find UTC time from given date... no 1900 correction! */
\r
729 public static double date_msecFromDate(double year, double mon,
\r
730 double mday, double hour,
\r
731 double min, double sec,
\r
738 day = MakeDay(year, mon, mday);
\r
739 time = MakeTime(hour, min, sec, msec);
\r
740 result = MakeDate(day, time);
\r
745 private static final int MAXARGS = 7;
\r
746 private static double jsStaticFunction_UTC(Object[] args) {
\r
747 double array[] = new double[MAXARGS];
\r
751 for (loop = 0; loop < MAXARGS; loop++) {
\r
752 if (loop < args.length) {
\r
753 d = ScriptRuntime.toNumber(args[loop]);
\r
754 if (d != d || Double.isInfinite(d)) {
\r
755 return ScriptRuntime.NaN;
\r
757 array[loop] = ScriptRuntime.toInteger(args[loop]);
\r
763 /* adjust 2-digit years into the 20th century */
\r
764 if (array[0] >= 0 && array[0] <= 99)
\r
767 /* if we got a 0 for 'date' (which is out of range)
\r
768 * pretend it's a 1. (So Date.UTC(1972, 5) works) */
\r
772 d = date_msecFromDate(array[0], array[1], array[2],
\r
773 array[3], array[4], array[5], array[6]);
\r
776 // return new Double(d);
\r
780 * Use ported code from jsdate.c rather than the locale-specific
\r
781 * date-parsing code from Java, to keep js and rhino consistent.
\r
782 * Is this the right strategy?
\r
785 /* for use by date_parse */
\r
787 /* replace this with byte arrays? Cheaper? */
\r
788 private static String wtb[] = {
\r
790 "monday", "tuesday", "wednesday", "thursday", "friday",
\r
791 "saturday", "sunday",
\r
792 "january", "february", "march", "april", "may", "june",
\r
793 "july", "august", "september", "october", "november", "december",
\r
794 "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
\r
795 "mst", "mdt", "pst", "pdt"
\r
796 /* time zone table needs to be expanded */
\r
799 private static int ttb[] = {
\r
800 -1, -2, 0, 0, 0, 0, 0, 0, 0, /* AM/PM */
\r
801 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
\r
802 10000 + 0, 10000 + 0, 10000 + 0, /* UT/UTC */
\r
803 10000 + 5 * 60, 10000 + 4 * 60, /* EDT */
\r
804 10000 + 6 * 60, 10000 + 5 * 60,
\r
805 10000 + 7 * 60, 10000 + 6 * 60,
\r
806 10000 + 8 * 60, 10000 + 7 * 60
\r
809 /* helper for date_parse */
\r
810 private static boolean date_regionMatches(String s1, int s1off,
\r
811 String s2, int s2off,
\r
814 boolean result = false;
\r
815 /* return true if matches, otherwise, false */
\r
816 int s1len = s1.length();
\r
817 int s2len = s2.length();
\r
819 while (count > 0 && s1off < s1len && s2off < s2len) {
\r
820 if (Character.toLowerCase(s1.charAt(s1off)) !=
\r
821 Character.toLowerCase(s2.charAt(s2off)))
\r
834 private static double date_parseString(String s) {
\r
847 double tzoffset = -1;
\r
850 boolean seenplusminus = false;
\r
852 if (s == null) // ??? Will s be null?
\r
853 return ScriptRuntime.NaN;
\r
854 limit = s.length();
\r
855 while (i < limit) {
\r
858 if (c <= ' ' || c == ',' || c == '-') {
\r
861 if (c == '-' && '0' <= si && si <= '9') {
\r
867 if (c == '(') { /* comments) */
\r
869 while (i < limit) {
\r
880 if ('0' <= c && c <= '9') {
\r
882 while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
\r
883 n = n * 10 + c - '0';
\r
887 /* allow TZA before the year, so
\r
888 * 'Wed Nov 05 21:49:11 GMT-0800 1997'
\r
891 /* uses of seenplusminus allow : in TZA, so Java
\r
892 * no-timezone style of GMT+4:30 works
\r
894 if ((prevc == '+' || prevc == '-')/* && year>=0 */) {
\r
895 /* make ':' case below change tzoffset */
\r
896 seenplusminus = true;
\r
900 n = n * 60; /* EG. "GMT-3" */
\r
902 n = n % 100 + n / 100 * 60; /* eg "GMT-0430" */
\r
903 if (prevc == '+') /* plus means east of GMT */
\r
905 if (tzoffset != 0 && tzoffset != -1)
\r
906 return ScriptRuntime.NaN;
\r
908 } else if (n >= 70 ||
\r
909 (prevc == '/' && mon >= 0 && mday >= 0 && year < 0)) {
\r
911 return ScriptRuntime.NaN;
\r
912 else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
\r
913 year = n < 100 ? n + 1900 : n;
\r
915 return ScriptRuntime.NaN;
\r
916 } else if (c == ':') {
\r
922 return ScriptRuntime.NaN;
\r
923 } else if (c == '/') {
\r
925 mon = /*byte*/ n-1;
\r
929 return ScriptRuntime.NaN;
\r
930 } else if (i < limit && c != ',' && c > ' ' && c != '-') {
\r
931 return ScriptRuntime.NaN;
\r
932 } else if (seenplusminus && n < 60) { /* handle GMT-3:30 */
\r
937 } else if (hour >= 0 && min < 0) {
\r
939 } else if (min >= 0 && sec < 0) {
\r
941 } else if (mday < 0) {
\r
944 return ScriptRuntime.NaN;
\r
947 } else if (c == '/' || c == ':' || c == '+' || c == '-') {
\r
952 while (i < limit) {
\r
954 if (!(('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z')))
\r
959 return ScriptRuntime.NaN;
\r
960 for (k = wtb.length; --k >= 0;)
\r
961 if (date_regionMatches(wtb[k], 0, s, st, i-st)) {
\r
962 int action = ttb[k];
\r
966 * AM/PM. Count 12:30 AM as 00:30, 12:30 PM as
\r
967 * 12:30, instead of blindly adding 12 if PM.
\r
969 if (hour > 12 || hour < 0) {
\r
970 return ScriptRuntime.NaN;
\r
972 if (action == -1 && hour == 12) { // am
\r
974 } else if (action == -2 && hour != 12) {// pm
\r
978 } else if (action <= 13) { /* month! */
\r
980 mon = /*byte*/ (action - 2);
\r
982 return ScriptRuntime.NaN;
\r
985 tzoffset = action - 10000;
\r
991 return ScriptRuntime.NaN;
\r
995 if (year < 0 || mon < 0 || mday < 0)
\r
996 return ScriptRuntime.NaN;
\r
1003 if (tzoffset == -1) { /* no time zone specified, have to use local */
\r
1005 time = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
\r
1006 return internalUTC(time);
\r
1009 msec = date_msecFromDate(year, mon, mday, hour, min, sec, 0);
\r
1010 msec += tzoffset * msPerMinute;
\r
1014 private static double jsStaticFunction_parse(String s) {
\r
1015 return date_parseString(s);
\r
1018 private static final int FORMATSPEC_FULL = 0;
\r
1019 private static final int FORMATSPEC_DATE = 1;
\r
1020 private static final int FORMATSPEC_TIME = 2;
\r
1022 private static String date_format(double t, int format) {
\r
1024 return jsFunction_NaN_date_str;
\r
1026 StringBuffer result = new StringBuffer(60);
\r
1027 double local = LocalTime(t);
\r
1029 /* offset from GMT in minutes. The offset includes daylight savings,
\r
1031 int minutes = (int) Math.floor((LocalTZA + DaylightSavingTA(t))
\r
1033 /* map 510 minutes to 0830 hours */
\r
1034 int offset = (minutes / 60) * 100 + minutes % 60;
\r
1036 String dateStr = Integer.toString(DateFromTime(local));
\r
1037 String hourStr = Integer.toString(HourFromTime(local));
\r
1038 String minStr = Integer.toString(MinFromTime(local));
\r
1039 String secStr = Integer.toString(SecFromTime(local));
\r
1040 String offsetStr = Integer.toString(offset > 0 ? offset : -offset);
\r
1041 int year = YearFromTime(local);
\r
1042 String yearStr = Integer.toString(year > 0 ? year : -year);
\r
1044 /* Tue Oct 31 09:41:40 GMT-0800 (PST) 2000 */
\r
1045 /* Tue Oct 31 2000 */
\r
1046 /* 09:41:40 GMT-0800 (PST) */
\r
1048 if (format != FORMATSPEC_TIME) {
\r
1049 result.append(days[WeekDay(local)]);
\r
1050 result.append(' ');
\r
1051 result.append(months[MonthFromTime(local)]);
\r
1052 if (dateStr.length() == 1)
\r
1053 result.append(" 0");
\r
1055 result.append(' ');
\r
1056 result.append(dateStr);
\r
1057 result.append(' ');
\r
1060 if (format != FORMATSPEC_DATE) {
\r
1061 if (hourStr.length() == 1)
\r
1062 result.append('0');
\r
1063 result.append(hourStr);
\r
1064 if (minStr.length() == 1)
\r
1065 result.append(":0");
\r
1067 result.append(':');
\r
1068 result.append(minStr);
\r
1069 if (secStr.length() == 1)
\r
1070 result.append(":0");
\r
1072 result.append(':');
\r
1073 result.append(secStr);
\r
1075 result.append(" GMT+");
\r
1077 result.append(" GMT-");
\r
1078 for (int i = offsetStr.length(); i < 4; i++)
\r
1079 result.append('0');
\r
1080 result.append(offsetStr);
\r
1082 if (timeZoneFormatter == null)
\r
1083 timeZoneFormatter = new java.text.SimpleDateFormat("zzz");
\r
1085 if (timeZoneFormatter != null) {
\r
1086 result.append(" (");
\r
1087 java.util.Date date = new Date((long) t);
\r
1088 result.append(timeZoneFormatter.format(date));
\r
1089 result.append(')');
\r
1091 if (format != FORMATSPEC_TIME)
\r
1092 result.append(' ');
\r
1095 if (format != FORMATSPEC_TIME) {
\r
1097 result.append('-');
\r
1098 for (int i = yearStr.length(); i < 4; i++)
\r
1099 result.append('0');
\r
1100 result.append(yearStr);
\r
1103 return result.toString();
\r
1106 /* the javascript constructor */
\r
1107 private static Object jsConstructor(Object[] args, boolean inNewExpr) {
\r
1108 // if called as a function, just return a string
\r
1109 // representing the current time.
\r
1111 return date_format(Now(), FORMATSPEC_FULL);
\r
1113 NativeDate obj = new NativeDate();
\r
1115 // if called as a constructor with no args,
\r
1116 // return a new Date with the current time.
\r
1117 if (args.length == 0) {
\r
1122 // if called with just one arg -
\r
1123 if (args.length == 1) {
\r
1125 if (args[0] instanceof Scriptable)
\r
1126 args[0] = ((Scriptable) args[0]).getDefaultValue(null);
\r
1127 if (!(args[0] instanceof String)) {
\r
1128 // if it's not a string, use it as a millisecond date
\r
1129 date = ScriptRuntime.toNumber(args[0]);
\r
1131 // it's a string; parse it.
\r
1132 String str = (String) args[0];
\r
1133 date = date_parseString(str);
\r
1135 obj.date = TimeClip(date);
\r
1139 // multiple arguments; year, month, day etc.
\r
1140 double array[] = new double[MAXARGS];
\r
1144 for (loop = 0; loop < MAXARGS; loop++) {
\r
1145 if (loop < args.length) {
\r
1146 d = ScriptRuntime.toNumber(args[loop]);
\r
1148 if (d != d || Double.isInfinite(d)) {
\r
1149 obj.date = ScriptRuntime.NaN;
\r
1152 array[loop] = ScriptRuntime.toInteger(args[loop]);
\r
1158 /* adjust 2-digit years into the 20th century */
\r
1159 if (array[0] >= 0 && array[0] <= 99)
\r
1162 /* if we got a 0 for 'date' (which is out of range)
\r
1163 * pretend it's a 1 */
\r
1167 double day = MakeDay(array[0], array[1], array[2]);
\r
1168 double time = MakeTime(array[3], array[4], array[5], array[6]);
\r
1169 time = MakeDate(day, time);
\r
1170 time = internalUTC(time);
\r
1171 obj.date = TimeClip(time);
\r
1176 /* constants for toString, toUTCString */
\r
1177 private static String jsFunction_NaN_date_str = "Invalid Date";
\r
1179 private static String[] days = {
\r
1180 "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
\r
1183 private static String[] months = {
\r
1184 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
\r
1185 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
\r
1188 private static String toLocale_helper(double t,
\r
1189 java.text.DateFormat formatter)
\r
1192 return jsFunction_NaN_date_str;
\r
1194 java.util.Date tempdate = new Date((long) t);
\r
1195 return formatter.format(tempdate);
\r
1198 private static String jsFunction_toLocaleString(double date) {
\r
1199 if (localeDateTimeFormatter == null)
\r
1200 localeDateTimeFormatter =
\r
1201 DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
\r
1203 return toLocale_helper(date, localeDateTimeFormatter);
\r
1206 private static String jsFunction_toLocaleTimeString(double date) {
\r
1207 if (localeTimeFormatter == null)
\r
1208 localeTimeFormatter = DateFormat.getTimeInstance(DateFormat.LONG);
\r
1210 return toLocale_helper(date, localeTimeFormatter);
\r
1213 private static String jsFunction_toLocaleDateString(double date) {
\r
1214 if (localeDateFormatter == null)
\r
1215 localeDateFormatter = DateFormat.getDateInstance(DateFormat.LONG);
\r
1217 return toLocale_helper(date, localeDateFormatter);
\r
1220 private static String jsFunction_toUTCString(double date) {
\r
1221 StringBuffer result = new StringBuffer(60);
\r
1223 String dateStr = Integer.toString(DateFromTime(date));
\r
1224 String hourStr = Integer.toString(HourFromTime(date));
\r
1225 String minStr = Integer.toString(MinFromTime(date));
\r
1226 String secStr = Integer.toString(SecFromTime(date));
\r
1227 int year = YearFromTime(date);
\r
1228 String yearStr = Integer.toString(year > 0 ? year : -year);
\r
1230 result.append(days[WeekDay(date)]);
\r
1231 result.append(", ");
\r
1232 if (dateStr.length() == 1)
\r
1233 result.append('0');
\r
1234 result.append(dateStr);
\r
1235 result.append(' ');
\r
1236 result.append(months[MonthFromTime(date)]);
\r
1238 result.append(" -");
\r
1240 result.append(' ');
\r
1242 for (i = yearStr.length(); i < 4; i++)
\r
1243 result.append('0');
\r
1244 result.append(yearStr);
\r
1246 if (hourStr.length() == 1)
\r
1247 result.append(" 0");
\r
1249 result.append(' ');
\r
1250 result.append(hourStr);
\r
1251 if (minStr.length() == 1)
\r
1252 result.append(":0");
\r
1254 result.append(':');
\r
1255 result.append(minStr);
\r
1256 if (secStr.length() == 1)
\r
1257 result.append(":0");
\r
1259 result.append(':');
\r
1260 result.append(secStr);
\r
1262 result.append(" GMT");
\r
1263 return result.toString();
\r
1266 private static double jsFunction_getYear(Context cx, double date) {
\r
1268 int result = YearFromTime(LocalTime(date));
\r
1270 if (cx.hasFeature(Context.FEATURE_NON_ECMA_GET_YEAR)) {
\r
1271 if (result >= 1900 && result < 2000) {
\r
1281 private static double jsFunction_getTimezoneOffset(double date) {
\r
1282 return (date - LocalTime(date)) / msPerMinute;
\r
1285 public double jsFunction_setTime(double time) {
\r
1286 this.date = TimeClip(time);
\r
1290 private double makeTime(Object[] args, int maxargs, boolean local) {
\r
1292 double conv[] = new double[4];
\r
1293 double hour, min, sec, msec;
\r
1294 double lorutime; /* Local or UTC version of date */
\r
1299 double date = this.date;
\r
1301 /* just return NaN if the date is already NaN */
\r
1305 /* Satisfy the ECMA rule that if a function is called with
\r
1306 * fewer arguments than the specified formal arguments, the
\r
1307 * remaining arguments are set to undefined. Seems like all
\r
1308 * the Date.setWhatever functions in ECMA are only varargs
\r
1309 * beyond the first argument; this should be set to undefined
\r
1310 * if it's not given. This means that "d = new Date();
\r
1311 * d.setMilliseconds()" returns NaN. Blech.
\r
1313 if (args.length == 0)
\r
1314 args = ScriptRuntime.padArguments(args, 1);
\r
1316 for (i = 0; i < args.length && i < maxargs; i++) {
\r
1317 conv[i] = ScriptRuntime.toNumber(args[i]);
\r
1319 // limit checks that happen in MakeTime in ECMA.
\r
1320 if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
\r
1321 this.date = ScriptRuntime.NaN;
\r
1324 conv[i] = ScriptRuntime.toInteger(conv[i]);
\r
1328 lorutime = LocalTime(date);
\r
1333 int stop = args.length;
\r
1335 if (maxargs >= 4 && i < stop)
\r
1338 hour = HourFromTime(lorutime);
\r
1340 if (maxargs >= 3 && i < stop)
\r
1343 min = MinFromTime(lorutime);
\r
1345 if (maxargs >= 2 && i < stop)
\r
1348 sec = SecFromTime(lorutime);
\r
1350 if (maxargs >= 1 && i < stop)
\r
1353 msec = msFromTime(lorutime);
\r
1355 time = MakeTime(hour, min, sec, msec);
\r
1356 result = MakeDate(Day(lorutime), time);
\r
1359 result = internalUTC(result);
\r
1360 date = TimeClip(result);
\r
1366 private double jsFunction_setHours(Object[] args) {
\r
1367 return makeTime(args, 4, true);
\r
1370 private double jsFunction_setUTCHours(Object[] args) {
\r
1371 return makeTime(args, 4, false);
\r
1374 private double makeDate(Object[] args, int maxargs, boolean local) {
\r
1376 double conv[] = new double[3];
\r
1377 double year, month, day;
\r
1378 double lorutime; /* local or UTC version of date */
\r
1381 double date = this.date;
\r
1383 /* See arg padding comment in makeTime.*/
\r
1384 if (args.length == 0)
\r
1385 args = ScriptRuntime.padArguments(args, 1);
\r
1387 for (i = 0; i < args.length && i < maxargs; i++) {
\r
1388 conv[i] = ScriptRuntime.toNumber(args[i]);
\r
1390 // limit checks that happen in MakeDate in ECMA.
\r
1391 if (conv[i] != conv[i] || Double.isInfinite(conv[i])) {
\r
1392 this.date = ScriptRuntime.NaN;
\r
1395 conv[i] = ScriptRuntime.toInteger(conv[i]);
\r
1398 /* return NaN if date is NaN and we're not setting the year,
\r
1399 * If we are, use 0 as the time. */
\r
1400 if (date != date) {
\r
1401 if (args.length < 3) {
\r
1402 return ScriptRuntime.NaN;
\r
1408 lorutime = LocalTime(date);
\r
1414 int stop = args.length;
\r
1416 if (maxargs >= 3 && i < stop)
\r
1419 year = YearFromTime(lorutime);
\r
1421 if (maxargs >= 2 && i < stop)
\r
1422 month = conv[i++];
\r
1424 month = MonthFromTime(lorutime);
\r
1426 if (maxargs >= 1 && i < stop)
\r
1429 day = DateFromTime(lorutime);
\r
1431 day = MakeDay(year, month, day); /* day within year */
\r
1432 result = MakeDate(day, TimeWithinDay(lorutime));
\r
1435 result = internalUTC(result);
\r
1437 date = TimeClip(result);
\r
1443 private double jsFunction_setYear(double year) {
\r
1444 double day, result;
\r
1445 if (year != year || Double.isInfinite(year)) {
\r
1446 this.date = ScriptRuntime.NaN;
\r
1450 if (this.date != this.date) {
\r
1453 this.date = LocalTime(this.date);
\r
1456 if (year >= 0 && year <= 99)
\r
1459 day = MakeDay(year, MonthFromTime(this.date), DateFromTime(this.date));
\r
1460 result = MakeDate(day, TimeWithinDay(this.date));
\r
1461 result = internalUTC(result);
\r
1463 this.date = TimeClip(result);
\r
1467 protected String getIdName(int id) {
\r
1468 if (prototypeFlag) {
\r
1470 case ConstructorId_UTC: return "UTC";
\r
1471 case ConstructorId_parse: return "parse";
\r
1472 case Id_constructor: return "constructor";
\r
1473 case Id_toString: return "toString";
\r
1474 case Id_toTimeString: return "toTimeString";
\r
1475 case Id_toDateString: return "toDateString";
\r
1476 case Id_toLocaleString: return "toLocaleString";
\r
1477 case Id_toLocaleTimeString: return "toLocaleTimeString";
\r
1478 case Id_toLocaleDateString: return "toLocaleDateString";
\r
1479 case Id_toUTCString: return "toUTCString";
\r
1480 case Id_valueOf: return "valueOf";
\r
1481 case Id_getTime: return "getTime";
\r
1482 case Id_getYear: return "getYear";
\r
1483 case Id_getFullYear: return "getFullYear";
\r
1484 case Id_getUTCFullYear: return "getUTCFullYear";
\r
1485 case Id_getMonth: return "getMonth";
\r
1486 case Id_getUTCMonth: return "getUTCMonth";
\r
1487 case Id_getDate: return "getDate";
\r
1488 case Id_getUTCDate: return "getUTCDate";
\r
1489 case Id_getDay: return "getDay";
\r
1490 case Id_getUTCDay: return "getUTCDay";
\r
1491 case Id_getHours: return "getHours";
\r
1492 case Id_getUTCHours: return "getUTCHours";
\r
1493 case Id_getMinutes: return "getMinutes";
\r
1494 case Id_getUTCMinutes: return "getUTCMinutes";
\r
1495 case Id_getSeconds: return "getSeconds";
\r
1496 case Id_getUTCSeconds: return "getUTCSeconds";
\r
1497 case Id_getMilliseconds: return "getMilliseconds";
\r
1498 case Id_getUTCMilliseconds: return "getUTCMilliseconds";
\r
1499 case Id_getTimezoneOffset: return "getTimezoneOffset";
\r
1500 case Id_setTime: return "setTime";
\r
1501 case Id_setMilliseconds: return "setMilliseconds";
\r
1502 case Id_setUTCMilliseconds: return "setUTCMilliseconds";
\r
1503 case Id_setSeconds: return "setSeconds";
\r
1504 case Id_setUTCSeconds: return "setUTCSeconds";
\r
1505 case Id_setMinutes: return "setMinutes";
\r
1506 case Id_setUTCMinutes: return "setUTCMinutes";
\r
1507 case Id_setHours: return "setHours";
\r
1508 case Id_setUTCHours: return "setUTCHours";
\r
1509 case Id_setDate: return "setDate";
\r
1510 case Id_setUTCDate: return "setUTCDate";
\r
1511 case Id_setMonth: return "setMonth";
\r
1512 case Id_setUTCMonth: return "setUTCMonth";
\r
1513 case Id_setFullYear: return "setFullYear";
\r
1514 case Id_setUTCFullYear: return "setUTCFullYear";
\r
1515 case Id_setYear: return "setYear";
\r
1521 // #string_id_map#
\r
1523 protected int mapNameToId(String s) {
\r
1524 if (!prototypeFlag) { return 0; }
\r
1526 // #generated# Last update: 2001-04-22 23:46:59 CEST
\r
1527 L0: { id = 0; String X = null; int c;
\r
1528 L: switch (s.length()) {
\r
1529 case 6: X="getDay";id=Id_getDay; break L;
\r
1530 case 7: switch (s.charAt(3)) {
\r
1531 case 'D': c=s.charAt(0);
\r
1532 if (c=='g') { X="getDate";id=Id_getDate; }
\r
1533 else if (c=='s') { X="setDate";id=Id_setDate; }
\r
1535 case 'T': c=s.charAt(0);
\r
1536 if (c=='g') { X="getTime";id=Id_getTime; }
\r
1537 else if (c=='s') { X="setTime";id=Id_setTime; }
\r
1539 case 'Y': c=s.charAt(0);
\r
1540 if (c=='g') { X="getYear";id=Id_getYear; }
\r
1541 else if (c=='s') { X="setYear";id=Id_setYear; }
\r
1543 case 'u': X="valueOf";id=Id_valueOf; break L;
\r
1545 case 8: c=s.charAt(0);
\r
1548 if (c=='h') { X="getMonth";id=Id_getMonth; }
\r
1549 else if (c=='s') { X="getHours";id=Id_getHours; }
\r
1551 else if (c=='s') {
\r
1553 if (c=='h') { X="setMonth";id=Id_setMonth; }
\r
1554 else if (c=='s') { X="setHours";id=Id_setHours; }
\r
1556 else if (c=='t') { X="toString";id=Id_toString; }
\r
1558 case 9: X="getUTCDay";id=Id_getUTCDay; break L;
\r
1559 case 10: c=s.charAt(3);
\r
1562 if (c=='g') { X="getMinutes";id=Id_getMinutes; }
\r
1563 else if (c=='s') { X="setMinutes";id=Id_setMinutes; }
\r
1565 else if (c=='S') {
\r
1567 if (c=='g') { X="getSeconds";id=Id_getSeconds; }
\r
1568 else if (c=='s') { X="setSeconds";id=Id_setSeconds; }
\r
1570 else if (c=='U') {
\r
1572 if (c=='g') { X="getUTCDate";id=Id_getUTCDate; }
\r
1573 else if (c=='s') { X="setUTCDate";id=Id_setUTCDate; }
\r
1576 case 11: switch (s.charAt(3)) {
\r
1577 case 'F': c=s.charAt(0);
\r
1578 if (c=='g') { X="getFullYear";id=Id_getFullYear; }
\r
1579 else if (c=='s') { X="setFullYear";id=Id_setFullYear; }
\r
1581 case 'M': X="toGMTString";id=Id_toGMTString; break L;
\r
1582 case 'T': X="toUTCString";id=Id_toUTCString; break L;
\r
1583 case 'U': c=s.charAt(0);
\r
1586 if (c=='r') { X="getUTCHours";id=Id_getUTCHours; }
\r
1587 else if (c=='t') { X="getUTCMonth";id=Id_getUTCMonth; }
\r
1589 else if (c=='s') {
\r
1591 if (c=='r') { X="setUTCHours";id=Id_setUTCHours; }
\r
1592 else if (c=='t') { X="setUTCMonth";id=Id_setUTCMonth; }
\r
1595 case 's': X="constructor";id=Id_constructor; break L;
\r
1597 case 12: c=s.charAt(2);
\r
1598 if (c=='D') { X="toDateString";id=Id_toDateString; }
\r
1599 else if (c=='T') { X="toTimeString";id=Id_toTimeString; }
\r
1601 case 13: c=s.charAt(0);
\r
1604 if (c=='M') { X="getUTCMinutes";id=Id_getUTCMinutes; }
\r
1605 else if (c=='S') { X="getUTCSeconds";id=Id_getUTCSeconds; }
\r
1607 else if (c=='s') {
\r
1609 if (c=='M') { X="setUTCMinutes";id=Id_setUTCMinutes; }
\r
1610 else if (c=='S') { X="setUTCSeconds";id=Id_setUTCSeconds; }
\r
1613 case 14: c=s.charAt(0);
\r
1614 if (c=='g') { X="getUTCFullYear";id=Id_getUTCFullYear; }
\r
1615 else if (c=='s') { X="setUTCFullYear";id=Id_setUTCFullYear; }
\r
1616 else if (c=='t') { X="toLocaleString";id=Id_toLocaleString; }
\r
1618 case 15: c=s.charAt(0);
\r
1619 if (c=='g') { X="getMilliseconds";id=Id_getMilliseconds; }
\r
1620 else if (c=='s') { X="setMilliseconds";id=Id_setMilliseconds; }
\r
1622 case 17: X="getTimezoneOffset";id=Id_getTimezoneOffset; break L;
\r
1623 case 18: c=s.charAt(0);
\r
1624 if (c=='g') { X="getUTCMilliseconds";id=Id_getUTCMilliseconds; }
\r
1625 else if (c=='s') { X="setUTCMilliseconds";id=Id_setUTCMilliseconds; }
\r
1626 else if (c=='t') {
\r
1628 if (c=='D') { X="toLocaleDateString";id=Id_toLocaleDateString; }
\r
1629 else if (c=='T') { X="toLocaleTimeString";id=Id_toLocaleTimeString; }
\r
1633 if (X!=null && X!=s && !X.equals(s)) id = 0;
\r
1639 private static final int
\r
1640 ConstructorId_UTC = -2,
\r
1641 ConstructorId_parse = -1,
\r
1643 Id_constructor = 1,
\r
1645 Id_toTimeString = 3,
\r
1646 Id_toDateString = 4,
\r
1647 Id_toLocaleString = 5,
\r
1648 Id_toLocaleTimeString = 6,
\r
1649 Id_toLocaleDateString = 7,
\r
1650 Id_toUTCString = 8,
\r
1654 Id_getFullYear = 12,
\r
1655 Id_getUTCFullYear = 13,
\r
1657 Id_getUTCMonth = 15,
\r
1659 Id_getUTCDate = 17,
\r
1661 Id_getUTCDay = 19,
\r
1663 Id_getUTCHours = 21,
\r
1664 Id_getMinutes = 22,
\r
1665 Id_getUTCMinutes = 23,
\r
1666 Id_getSeconds = 24,
\r
1667 Id_getUTCSeconds = 25,
\r
1668 Id_getMilliseconds = 26,
\r
1669 Id_getUTCMilliseconds = 27,
\r
1670 Id_getTimezoneOffset = 28,
\r
1672 Id_setMilliseconds = 30,
\r
1673 Id_setUTCMilliseconds = 31,
\r
1674 Id_setSeconds = 32,
\r
1675 Id_setUTCSeconds = 33,
\r
1676 Id_setMinutes = 34,
\r
1677 Id_setUTCMinutes = 35,
\r
1679 Id_setUTCHours = 37,
\r
1681 Id_setUTCDate = 39,
\r
1683 Id_setUTCMonth = 41,
\r
1684 Id_setFullYear = 42,
\r
1685 Id_setUTCFullYear = 43,
\r
1688 MAX_PROTOTYPE_ID = 44;
\r
1690 private static final int
\r
1691 Id_toGMTString = Id_toUTCString; // Alias, see Ecma B.2.6
\r
1692 // #/string_id_map#
\r
1694 /* cached values */
\r
1695 private static java.util.TimeZone thisTimeZone;
\r
1696 private static double LocalTZA;
\r
1697 private static java.text.DateFormat timeZoneFormatter;
\r
1698 private static java.text.DateFormat localeDateTimeFormatter;
\r
1699 private static java.text.DateFormat localeDateFormatter;
\r
1700 private static java.text.DateFormat localeTimeFormatter;
\r
1702 private double date;
\r
1704 private boolean prototypeFlag;
\r