?? nativedate.java
字號:
} private static int YearFromTime(double t) { int lo = (int) Math.floor((t / msPerDay) / 366) + 1970; int hi = (int) Math.floor((t / msPerDay) / 365) + 1970; int mid; /* above doesn't work for negative dates... */ if (hi < lo) { int temp = lo; lo = hi; hi = temp; } /* Use a simple binary search algorithm to find the right year. This seems like brute force... but the computation of hi and lo years above lands within one year of the correct answer for years within a thousand years of 1970; the loop below only requires six iterations for year 270000. */ while (hi > lo) { mid = (hi + lo) / 2; if (TimeFromYear(mid) > t) { hi = mid - 1; } else { lo = mid + 1; if (TimeFromYear(lo) > t) { return mid; } } } return lo; } private static boolean InLeapYear(double t) { return IsLeapYear(YearFromTime(t)); } private static double DayFromMonth(int m, int year) { int day = m * 30; if (m >= 7) { day += m / 2 - 1; } else if (m >= 2) { day += (m - 1) / 2 - 1; } else { day += m; } if (m >= 2 && IsLeapYear(year)) { ++day; } return day; } private static int MonthFromTime(double t) { int year = YearFromTime(t); int d = (int)(Day(t) - DayFromYear(year)); d -= 31 + 28; if (d < 0) { return (d < -28) ? 0 : 1; } if (IsLeapYear(year)) { if (d == 0) return 1; // 29 February --d; } // d: date count from 1 March int estimate = d / 30; // approx number of month since March int mstart; switch (estimate) { case 0: return 2; case 1: mstart = 31; break; case 2: mstart = 31+30; break; case 3: mstart = 31+30+31; break; case 4: mstart = 31+30+31+30; break; case 5: mstart = 31+30+31+30+31; break; case 6: mstart = 31+30+31+30+31+31; break; case 7: mstart = 31+30+31+30+31+31+30; break; case 8: mstart = 31+30+31+30+31+31+30+31; break; case 9: mstart = 31+30+31+30+31+31+30+31+30; break; case 10: return 11; //Late december default: throw Kit.codeBug(); } // if d < mstart then real month since March == estimate - 1 return (d >= mstart) ? estimate + 2 : estimate + 1; } private static int DateFromTime(double t) { int year = YearFromTime(t); int d = (int)(Day(t) - DayFromYear(year)); d -= 31 + 28; if (d < 0) { return (d < -28) ? d + 31 + 28 + 1 : d + 28 + 1; } if (IsLeapYear(year)) { if (d == 0) return 29; // 29 February --d; } // d: date count from 1 March int mdays, mstart; switch (d / 30) { // approx number of month since March case 0: return d + 1; case 1: mdays = 31; mstart = 31; break; case 2: mdays = 30; mstart = 31+30; break; case 3: mdays = 31; mstart = 31+30+31; break; case 4: mdays = 30; mstart = 31+30+31+30; break; case 5: mdays = 31; mstart = 31+30+31+30+31; break; case 6: mdays = 31; mstart = 31+30+31+30+31+31; break; case 7: mdays = 30; mstart = 31+30+31+30+31+31+30; break; case 8: mdays = 31; mstart = 31+30+31+30+31+31+30+31; break; case 9: mdays = 30; mstart = 31+30+31+30+31+31+30+31+30; break; case 10: return d - (31+30+31+30+31+31+30+31+30) + 1; //Late december default: throw Kit.codeBug(); } d -= mstart; if (d < 0) { // wrong estimate: sfhift to previous month d += mdays; } return d + 1; } private static int WeekDay(double t) { double result; result = Day(t) + 4; result = result % 7; if (result < 0) result += 7; return (int) result; } private static double now() { return (double) System.currentTimeMillis(); } /* Should be possible to determine the need for this dynamically * if we go with the workaround... I'm not using it now, because I * can't think of any clean way to make toLocaleString() and the * time zone (comment) in toString match the generated string * values. Currently it's wrong-but-consistent in all but the * most recent betas of the JRE - seems to work in 1.1.7. */ private final static boolean TZO_WORKAROUND = false; private static double DaylightSavingTA(double t) { // Another workaround! The JRE doesn't seem to know about DST // before year 1 AD, so we map to equivalent dates for the // purposes of finding dst. To be safe, we do this for years // outside 1970-2038. if (t < 0.0 || t > 2145916800000.0) { int year = EquivalentYear(YearFromTime(t)); double day = MakeDay(year, MonthFromTime(t), DateFromTime(t)); t = MakeDate(day, TimeWithinDay(t)); } if (!TZO_WORKAROUND) { Date date = new Date((long) t); if (thisTimeZone.inDaylightTime(date)) return msPerHour; else return 0; } else { /* Use getOffset if inDaylightTime() is broken, because it * seems to work acceptably. We don't switch over to it * entirely, because it requires (expensive) exploded date arguments, * and the api makes it impossible to handle dst * changeovers cleanly. */ // Hardcode the assumption that the changeover always // happens at 2:00 AM: t += LocalTZA + (HourFromTime(t) <= 2 ? msPerHour : 0); int year = YearFromTime(t); double offset = thisTimeZone.getOffset(year > 0 ? 1 : 0, year, MonthFromTime(t), DateFromTime(t), WeekDay(t), (int)TimeWithinDay(t)); if ((offset - LocalTZA) != 0) return msPerHour; else return 0; // return offset - LocalTZA; } } /* * Find a year for which any given date will fall on the same weekday. * * This function should be used with caution when used other than * for determining DST; it hasn't been proven not to produce an * incorrect year for times near year boundaries. */ private static int EquivalentYear(int year) { int day = (int) DayFromYear(year) + 4; day = day % 7; if (day < 0) day += 7; // Years and leap years on which Jan 1 is a Sunday, Monday, etc. if (IsLeapYear(year)) { switch (day) { case 0: return 1984; case 1: return 1996; case 2: return 1980; case 3: return 1992; case 4: return 1976; case 5: return 1988; case 6: return 1972; } } else { switch (day) { case 0: return 1978; case 1: return 1973; case 2: return 1974; case 3: return 1975; case 4: return 1981; case 5: return 1971; case 6: return 1977; } } // Unreachable throw Kit.codeBug(); } private static double LocalTime(double t) { return t + LocalTZA + DaylightSavingTA(t); } private static double internalUTC(double t) { return t - LocalTZA - DaylightSavingTA(t - LocalTZA); } private static int HourFromTime(double t) { double result; result = Math.floor(t / msPerHour) % HoursPerDay; if (result < 0) result += HoursPerDay; return (int) result; } private static int MinFromTime(double t) { double result; result = Math.floor(t / msPerMinute) % MinutesPerHour; if (result < 0) result += MinutesPerHour; return (int) result; } private static int SecFromTime(double t) { double result; result = Math.floor(t / msPerSecond) % SecondsPerMinute; if (result < 0) result += SecondsPerMinute; return (int) result; } private static int msFromTime(double t) { double result; result = t % msPerSecond; if (result < 0) result += msPerSecond; return (int) result; } private static double MakeTime(double hour, double min, double sec, double ms) { return ((hour * MinutesPerHour + min) * SecondsPerMinute + sec) * msPerSecond + ms; } private static double MakeDay(double year, double month, double date) { year += Math.floor(month / 12); month = month % 12; if (month < 0) month += 12; double yearday = Math.floor(TimeFromYear(year) / msPerDay); double monthday = DayFromMonth((int)month, (int)year); return yearday + monthday + date - 1; } private static double MakeDate(double day, double time) { return day * msPerDay + time; } private static double TimeClip(double d) { if (d != d || d == Double.POSITIVE_INFINITY || d == Double.NEGATIVE_INFINITY || Math.abs(d) > HalfTimeDomain) { return ScriptRuntime.NaN; } if (d > 0.0) return Math.floor(d + 0.); else return Math.ceil(d + 0.); } /* end of ECMA helper functions */ /* find UTC time from given date... no 1900 correction! */ private static double date_msecFromDate(double year, double mon, double mday, double hour, double min, double sec, double msec) { double day; double time; double result; day = MakeDay(year, mon, mday); time = MakeTime(hour, min, sec, msec); result = MakeDate(day, time); return result; } private static final int MAXARGS = 7; private static double jsStaticFunction_UTC(Object[] args) { double array[] = new double[MAXARGS]; int loop; double d; for (loop = 0; loop < MAXARGS; loop++) { if (loop < args.length) { d = ScriptRuntime.toNumber(args[loop]); if (d != d || Double.isInfinite(d)) { return ScriptRuntime.NaN; } array[loop] = ScriptRuntime.toInteger(args[loop]); } else { } } /* adjust 2-digit years into the 20th century */ if (array[0] >= 0 && array[0] <= 99) array[0] += 1900; /* if we got a 0 for 'date' (which is out of range) * pretend it's a 1. (So Date.UTC(1972, 5) works) */ if (array[2] < 1) array[2] = 1; d = date_msecFromDate(array[0], array[1], array[2], array[3], array[4], array[5], array[6]); d = TimeClip(d); return d; } private static double date_parseString(String s) { int year = -1; int mon = -1; int mday = -1; int hour = -1; int min = -1; int sec = -1; char c = 0; char si = 0; int i = 0; int n = -1; double tzoffset = -1; char prevc = 0; int limit = 0; boolean seenplusminus = false; limit = s.length(); while (i < limit) { c = s.charAt(i); i++; if (c <= ' ' || c == ',' || c == '-') { if (i < limit) { si = s.charAt(i); if (c == '-' && '0' <= si && si <= '9') { prevc = c; } }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -