qdate.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,666 行 · 第 1/3 页
JAVA
1,666 行
return _shortTimeFormat.format(_date); } /* * XXX: okay, this is vile. * Mon, 17 Jan 1994 11:14:55 -0500 (EST) * * In local time */ public long parseLocalDate(String string) throws Exception { long time = parseDate(string); synchronized (this) { setLocalTime(time); return getGMTTime(); } } /* * XXX: okay, this is vile. * Mon, 17 Jan 1994 11:14:55 -0500 (EST) * * In GMT time */ public long parseDate(String string) throws Exception { try { int strlen = string.length(); if (strlen == 0) return 0; int i = skipWhitespace(string, strlen, 0); int ch = string.charAt(i); if (ch >= '0' && ch <= '9' || (ch == 'T' && i + 1 < strlen && string.charAt(i + 1) >= '0' && string.charAt(i + 1) <= '9')) return parseISO8601Date(string, i); CharBuffer cb = new CharBuffer(); i = scan(string, 0, cb, true); if (cb.length() == 0 || ! Character.isDigit(cb.charAt(0))) i = scan(string, i, cb, true); int dayOfMonth = parseInt(cb); i = scan(string, i, cb, true); String smonth = cb.toString(); int month; for (month = 0; month < 12; month++) { if (MONTH_NAMES[(int) month].equalsIgnoreCase(smonth)) break; } if (month == 12) throw new Exception("Unexpected month: " + month); i = scan(string, i, cb, true); int year = parseInt(cb); if (cb.length() < 3 && year < 50) year += 2000; else if (cb.length() < 3 && year < 100) year += 1900; i = scan(string, i, cb, false); long timeOfDay = parseInt(cb) * 3600000; i = scan(string, i, cb, false); timeOfDay += parseInt(cb) * 60000; i = scan(string, i, cb, false); timeOfDay += parseInt(cb) * 1000; // XXX: gross hack if (year <= 1600) dayOfMonth--; long time = (MS_PER_DAY * (yearToDayOfEpoch(year) + monthToDayOfYear(month, isLeapYear(year)) + dayOfMonth - 1) + timeOfDay); try { i = scan(string, i, cb, false); for (int j = 0; j < cb.length(); j++) { if ((ch = cb.charAt(j)) == ';' || ch == ' ') cb.setLength(j); } ch = cb.length() > 0 ? cb.charAt(0) : 0; if (ch == '-' || ch == '+' || ch >= '0' && ch <= '9') { long zoneOffset; zoneOffset = parseInt(cb); zoneOffset = 60000 * (60 * (zoneOffset / 100) + zoneOffset % 100); time -= zoneOffset; setGMTTime(time); } else if (cb.equalsIgnoreCase("gmt") || cb.equalsIgnoreCase("utc")) { setGMTTime(time); } else { setLocalTime(time); } } catch (Exception e) { log.log(Level.FINER, e.toString(), e); } return _localTimeOfEpoch - _zoneOffset; } catch (Exception e) { log.log(Level.FINER, e.toString(), e); return Long.MAX_VALUE; } } private long parseISO8601Date(String string, int pos) throws Exception { int strlen = string.length(); int year = 0; int i; char ch = string.charAt(pos); if ('0' <= ch && ch <= '9') { year = scanISOInt(string, pos, strlen, 4); pos += 4; } if (pos < strlen && string.charAt(pos) == '-') pos++; int month = 0; if (pos < strlen && '0' <= (ch = string.charAt(pos)) && ch <= '9') { month = scanISOInt(string, pos, strlen, 2); month--; pos += 2; } else if (ch == 'W') return Long.MAX_VALUE; if (pos < strlen && string.charAt(pos) == '-') pos++; int day = 0; if (pos < strlen && '0' <= (ch = string.charAt(pos)) && ch <= '9') { day = scanISOInt(string, pos, strlen, 2); day--; pos += 2; } int hour = 0; int minute = 0; int second = 0; int millisecond = 0; if (pos < strlen && string.charAt(pos) == 'T') { pos++; if (pos < strlen && '0' <= (ch = string.charAt(pos)) && ch <= '9') { hour = scanISOInt(string, pos, strlen, 2); pos += 2; } // XXX: fractions can technically be used anywhere by using a // , or . instead of a : // e.g. 14:30,5 == 14:30:30 if (pos < strlen && string.charAt(pos) == ':') pos++; if (pos < strlen && '0' <= (ch = string.charAt(pos)) && ch <= '9') { minute = scanISOInt(string, pos, strlen, 2); pos += 2; } if (pos < strlen && string.charAt(pos) == ':') pos++; if (pos < strlen && '0' <= (ch = string.charAt(pos)) && ch <= '9') { second = scanISOInt(string, pos, strlen, 2); pos += 2; } if (pos < strlen && (string.charAt(pos) == '.' || string.charAt(pos) == ',')) { pos++; // XXX: fractions can be any strlen, not just 3 millisecond = scanISOInt(string, pos, strlen, 3); pos += 3; } } long timeOfDay = millisecond + 1000 * (second + 60 * (minute + 60 * hour)); // XXX: gross hack if (year <= 1600) day--; long time = (MS_PER_DAY * (yearToDayOfEpoch(year) + monthToDayOfYear(month, isLeapYear(year)) + day) + timeOfDay); if (strlen <= pos) { setLocalTime(time); return _localTimeOfEpoch; } if (string.charAt(pos) == 'Z') { pos++; } else if (string.charAt(pos) == '-' || string.charAt(pos) == '+') { int sign = -1; if (string.charAt(pos) == '-') sign = 1; pos++; int tzHour = scanISOInt(string, pos, strlen, 2); pos += 2; int tzMinute = 0; if (pos < strlen && string.charAt(pos) == ':') pos++; if (pos < strlen && '0' <= (ch = string.charAt(pos)) && ch <= '9') { tzMinute = scanISOInt(string, pos, strlen, 2); pos += 2; } time += sign * 1000 * (60 * (tzMinute + 60 * tzHour)); } else { setLocalTime(time); return _localTimeOfEpoch; } pos = skipWhitespace(string, strlen, pos); if (pos < strlen) throw new Exception("extra junk at end of ISO date"); setGMTTime(time); return _localTimeOfEpoch; } /** * Based on the year, return the number of days since the epoch. */ private long yearToDayOfEpoch(long year) { if (year > 0) { year -= 1601; return (365 * year + year / 4 - year / 100 + year / 400 - ((1970 - 1601) * 365 + (1970 - 1601) / 4 - 3)); } else { year = 2000 - year; return ((2000 - 1970) * 365 + (2000 - 1970) / 4 - (365 * year + year / 4 - year / 100 + year / 400)); } } /** * Calculates the day of the year for the beginning of the month. */ private long monthToDayOfYear(long month, boolean isLeapYear) { long day = 0; for (int i = 0; i < month && i < 12; i++) { day += DAYS_IN_MONTH[i]; if (i == 1 && isLeapYear) day++; } return day; } /** * Returns true if the given year is a leap year. */ private boolean isLeapYear(long year) { return ! ((_year % 4) != 0 || (_year % 100) == 0 && (_year % 400) != 0); } private int scanISOInt(String string, int pos, int length, int digits) throws Exception { int value = 0; for (int i = 0; i < digits; i++) { if (pos >= length) throw new Exception("expected ISO8601 digit"); char ch = string.charAt(pos++); if ('0' <= ch && ch <= '9') value = 10 * value + ch - '0'; else throw new Exception("expected ISO8601 digit"); } return value; } private int skipWhitespace(String string, int strlen, int i) { char ch; for (; i < strlen && ((ch = string.charAt(i)) == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); i++) { } return i; } /* * Scan to whitespace or ':' */ private int scan(String string, int i, CharBuffer cb, boolean dash) throws Exception { char ch; cb.setLength(0); int strlen = string.length(); for (; i < strlen; i++) { if (! Character.isWhitespace(ch = string.charAt(i)) && (ch != ':' && (! dash || ch != '-'))) break; } for (; i < strlen; i++) { if (! Character.isWhitespace(ch = string.charAt(i)) && (ch != ':' && (! dash || ch != '-'))) cb.append((char) ch); else break; } if (cb.length() == 0) throw new Exception(); return i; } private int parseInt(CharBuffer cb) throws Exception { int value = 0; int sign = 1; for (int i = 0; i < cb.length(); i++) { int ch = cb.charAt(i); if (i == 0 && ch == '-') sign = -1; else if (i == 0 && ch == '+') { } else if (ch >= '0' && ch <= '9') value = 10 * value + ch - '0'; else throw new Exception(); } return sign * value; } /** * Sets date in the local time. * * @param year * @param month where January = 0 * @param day day of month where the 1st = 1 */ public long setDate(long year, long month, long day) { year += (long) Math.floor(month / 12.0); month -= (long) 12 * Math.floor(month / 12.0); _year = year; _month = month; _dayOfMonth = day - 1; calculateJoin(); calculateSplit(_localTimeOfEpoch); return _localTimeOfEpoch; } public long setTime(long hour, long minute, long second, long ms) { _hour = hour; _minute = minute; _second = second; _ms = ms; calculateJoin(); calculateSplit(_localTimeOfEpoch); return _localTimeOfEpoch; } /** * Calculate and set the calendar components based on the given time. * * @param localTime local time in milliseconds since the epoch */ private void calculateSplit(long localTime) { _localTimeOfEpoch = localTime; _dayOfEpoch = divFloor(_localTimeOfEpoch, MS_PER_DAY); _timeOfDay = _localTimeOfEpoch - MS_PER_DAY * _dayOfEpoch; calculateYear(); calculateMonth(); _hour = _timeOfDay / 3600000; _minute = _timeOfDay / 60000 % 60; _second = _timeOfDay / 1000 % 60; _ms = _timeOfDay % 1000; if (_timeZone == _gmtTimeZone) { _isDaylightTime = false; _zoneName = _stdName; } else { _zoneOffset = _timeZone.getOffset(GregorianCalendar.AD, (int) _year, (int) _month, (int) _dayOfMonth + 1, getDayOfWeek(), (int) _timeOfDay); if (_zoneOffset == _timeZone.getRawOffset()) { _isDaylightTime = false; _zoneName = _stdName; } else { _isDaylightTime = true; _zoneName = _dstName; } } _calendar.setTime(new Date(_localTimeOfEpoch)); } /** * Calculates the year, the dayOfYear and whether this is a leap year * from the current days since the epoch. */ private void calculateYear() { long days = _dayOfEpoch; // shift to using 1601 as a base days += (1970 - 1601) * 365 + (1970 - 1601) / 4 - 3; long n400 = divFloor(days, 400 * 365 + 100 - 3); days -= n400 * (400 * 365 + 100 - 3); long n100 = divFloor(days, 100 * 365 + 25 - 1); if (n100 == 4) n100 = 3; days -= n100 * (100 * 365 + 25 - 1); long n4 = divFloor(days, 4 * 365 + 1); if (n4 == 25) n4 = 24; days -= n4 * (4 * 365 + 1); long n1 = divFloor(days, 365); if (n1 == 4) n1 = 3; _year = 400 * n400 + 100 * n100 + 4 * n4 + n1 + 1601; _dayOfYear = (int) (days - 365 * n1); _isLeapYear = isLeapYear(_year); } public boolean isLeapYear() { return _isLeapYear; } /** * Calculates the month based on the day of the year. */ private void calculateMonth() { _dayOfMonth = _dayOfYear; for (_month = 0; _month < 12; _month++) { if (_month == 1 && _isLeapYear) { if (_dayOfMonth < 29) return; else _dayOfMonth -= 29; } else if (_dayOfMonth < DAYS_IN_MONTH[(int) _month]) return; else _dayOfMonth -= DAYS_IN_MONTH[(int) _month]; } } /** * Based on the current data, calculate the time since the epoch. * * @return time since the epoch, given the calendar components */ private long calculateJoin() { _year += divFloor(_month, 12); _month -= 12 * divFloor(_month, 12); _localTimeOfEpoch = MS_PER_DAY * (yearToDayOfEpoch(_year) + monthToDayOfYear(_month, isLeapYear(_year)) + _dayOfMonth); _localTimeOfEpoch += _ms + 1000 * (_second + 60 * (_minute + 60 * _hour)); return _localTimeOfEpoch; } private long divFloor(long n, long d) { if (n > 0) return n / d; else return (n - d + 1) / d; } @Override public Object clone() { QDate newObj = new QDate(_timeZone); newObj.calculateSplit(_localTimeOfEpoch); return newObj; } @Override public String toString() { return "QDate[" + printDate() + "]"; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?