📄 calendar.java
字号:
zone = TimeZone.getDefault(); if (zone == null) { throw new RuntimeException("Could not find default timezone"); } setTimeInMillis(System.currentTimeMillis()); } /** * Gets this Calendar's current time. * * @return the current time. * * @see #setTime */ public final Date getTime() { if (date == null) return date = new Date( getTimeInMillis() ); else { synchronized (date) { date.setTime( getTimeInMillis() ); return date; } } } /** * Sets this Calendar's current time with the given Date. * <p> * Note: Calling <code>setTime()</code> with * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code> * may yield incorrect field values from <code>get()</code>. * * @param date the given Date. * * @see #getTime */ public final void setTime(Date date) { setTimeInMillis( date.getTime() ); } /** * Gets a calendar using the default time zone and default locale. * * @return a Calendar. */ /* <p> * The following is information for implementers. Applications should * not need to be aware of this or rely on it, because each * implementation may do it differently: * <p> * The Calendar will look up a class the name of which includes * the platform name. The class name will take the form: <p> * * <code>{classRoot}.util.{platform}.CalendarImpl</code> * * <p> * The classRoot is derived from the system by looking up the system * property "microedition.implpath". If this property key is not * found or the associated class is not present then "com.sun.cldc" * is used. * <p> * The platform name is derived from the system by looking for the * system property "microedition.platform". * If this property key is not found or the associated class is * not present then one of two default directories are used. * These are called "j2me" and "j2se". If the property * "microedition.configuration" is non-null then "j2me" is * used, otherwise "j2se" is assumed. * */ public static synchronized Calendar getInstance() { if (platform == null) { /* Setup the platform name *//**** platform = System.getProperty("microedition.platform"); if (platform == null) { // Work out if we are running on a J2ME system if (System.getProperty("microedition.configuration") != null) platform = "j2me"; else platform = "j2se"; }****/ platform = "j2me"; /* See if there is an alternate protocol class root */ classRoot = System.getProperty("microedition.implpath"); if (classRoot == null) { classRoot = "com.sun.cldc"; } } try { /* Using the platform and protocol names lookup a class to implement the connection */ Class clazz = Class.forName(classRoot+".util."+platform+".CalendarImpl"); /* Construct a new instance */ return (Calendar)clazz.newInstance(); } catch (Exception x) {} return null; } /** * Gets a calendar using the specified time zone and default locale. * @param zone the time zone to use * @return a Calendar. */ public static synchronized Calendar getInstance(TimeZone zone) { Calendar cal = getInstance(); cal.setTimeZone(zone); return cal; } /** * Gets this Calendar's current time as a long expressed in milliseconds * after January 1, 1970, 0:00:00 GMT (the epoch). * * @return the current time as UTC milliseconds from the epoch. * * @see #setTimeInMillis */ protected long getTimeInMillis() { if (!millisSet) { calculateTime(); millisSet = true; } return time; } /** * Sets this Calendar's current time from the given long value. * @param millis the new time in UTC milliseconds from the epoch. * * @see #getTimeInMillis */ protected void setTimeInMillis( long millis ) { millisSet = true; day_field = 0; time = millis; calculateFields(); } /** * Gets the value for a given time field. * @param field the given time field (either YEAR, MONTH, DATE, DAY_OF_WEEK, * HOUR_OF_DAY, HOUR, AM_PM, MINUTE, * SECOND, or MILLISECOND * @return the value for the given time field. * @exception ArrayIndexOutOfBoundsException if the parameter is not * one of the above. */ public final int get(int field) { switch (field) { case YEAR: return packed_date >> 9; case MONTH: return (packed_date >> 5) & 15; case DATE: return packed_date & 31; case DAY_OF_WEEK: { if (day_field == 0) { getTimeInMillis(); calculateFields(); } return day_field; } case HOUR_OF_DAY: return packed_time >> 22; case HOUR: { int hr = (packed_time >> 22) % 12; return hr == 0? 12 : hr; } case AM_PM: return (packed_time >> 22) < 12? AM: PM; case MINUTE: return (packed_time >> 16) & 63; case SECOND: return (packed_time >> 10) & 63; case MILLISECOND: return packed_time & 1023; } throw new ArrayIndexOutOfBoundsException(); } /** * Sets the time field with the given value. * * @param field the given time field. * Note that the DAY_OF_WEEK field cannot be set. * @param value the value to be set for the given time field. * * @exception ArrayIndexOutOfBoundsException if an illegal field * parameter is received. */ public final void set(int field, int value) { millisSet = false; day_field = 0; switch (field) { case YEAR: // 16383 = (2 to the power 14) - 1 packed_date = (packed_date & 511) | (value << 9); break; case MONTH: packed_date = (packed_date & (~(15<<5))) | ((value & 15) << 5); break; case DATE: packed_date = (packed_date & (~31)) | (value & 31); break; case HOUR_OF_DAY: value = value % 24; packed_time = (packed_time & 4194303) | (value << 22); hour_12hr = am_pm_12hr = -1; break; case HOUR: { if (value > 12) value = 12; if (am_pm_12hr != -1) { if (am_pm_12hr == PM) { if (value != 12) value += 12; } else if (value == 12) value = 0; hour_12hr = am_pm_12hr = -1; } else hour_12hr = value; packed_time = (packed_time & 4194303) | (value << 22); break; } case AM_PM: { if (hour_12hr != -1) { if (value == PM) { if (hour_12hr != 12) hour_12hr += 12; } else if (hour_12hr == 12) hour_12hr = 0; packed_time = (packed_time & 4194303) | (hour_12hr << 22); hour_12hr = am_pm_12hr = -1; } else am_pm_12hr = value; break; } case MINUTE: packed_time = (packed_time & (~(63<<16))) | ((value & 63) << 16); break; case SECOND: packed_time = (packed_time & (~(63<<10))) | ((value & 63) << 10); break; case MILLISECOND: packed_time = (packed_time & (~1023)) | (value & 1023); break; default: throw new ArrayIndexOutOfBoundsException(); } dstSet = false; } /** * Compares this calendar to the specified object. * The result is <code>true</code> if and only if the argument is * not <code>null</code> and is a <code>Calendar</code> object that * represents the same calendar as this object. * @param obj the object to compare with. * @return <code>true</code> if the objects are the same; * <code>false</code> otherwise. */ public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof Calendar)) return false; Calendar that = (Calendar)obj; return getTimeInMillis() == that.getTimeInMillis() && zone.equals(that.zone); } /** * Compares the time field records. * Equivalent to comparing result of conversion to UTC. * @param when the Calendar to be compared with this Calendar. * @return true if the current time of this Calendar is before * the time of Calendar when; false otherwise. */ public boolean before(Object when) { return (when instanceof Calendar && getTimeInMillis() < ((Calendar)when).getTimeInMillis()); } /** * Compares the time field records. * Equivalent to comparing result of conversion to UTC. * @param when the Calendar to be compared with this Calendar. * @return true if the current time of this Calendar is after * the time of Calendar when; false otherwise. */ public boolean after(Object when) { return (when instanceof Calendar && getTimeInMillis() > ((Calendar)when).getTimeInMillis()); } /** * Sets the time zone with the given time zone value. * @param value the given time zone. * * @see #getTimeZone */ public void setTimeZone(TimeZone value) { zone = value; getTimeInMillis(); calculateFields(); } /** * Gets the time zone. * @return the time zone object associated with this calendar. * * @see #setTimeZone */ public TimeZone getTimeZone() { return zone; } ///////////////////////////// // Time => Fields computation ///////////////////////////// private void calculateDstOffset() { if (day_field == 0) { getTimeInMillis(); calculateFields(); } int rawOffset = zone.getRawOffset(); long localMillis = time + rawOffset; long days = (long) (localMillis / ONE_DAY); int millisInDay = (int) (localMillis - (days * ONE_DAY)); if (millisInDay < 0) millisInDay += ONE_DAY; dstOffset = zone.getOffset(1, packed_date >> 9, (packed_date >> 5) & 15, packed_date & 31, day_field, millisInDay) - rawOffset; dstSet = true; } /** * Converts UTC as milliseconds to time field values. */ private void calculateFields() { int rawOffset = zone.getRawOffset(); long localMillis = time + rawOffset; /* Check for very extreme values -- millis near Long.MIN_VALUE or * Long.MAX_VALUE. For these values, adding the zone offset can push * the millis past MAX_VALUE to MIN_VALUE, or vice versa. This produces * the undesirable effect that the time can wrap around at the ends, * yielding, for example, a Date(Long.MAX_VALUE) with a big BC year * (should be AD). Handle this by pinning such values to Long.MIN_VALUE * or Long.MAX_VALUE. - liu 8/11/98 bug 4149677 */ if (time > 0 && localMillis < 0 && rawOffset > 0) { localMillis = Long.MAX_VALUE; } else if (time < 0 && localMillis > 0 && rawOffset < 0) { localMillis = Long.MIN_VALUE; } // Time to fields takes the wall millis (Standard or DST). timeToFields(localMillis); long days = (long) (localMillis / ONE_DAY); int millisInDay = (int) (localMillis - (days * ONE_DAY)); if (millisInDay < 0) millisInDay += ONE_DAY; // Call getOffset() to get the TimeZone offset. The millisInDay value must // be standard local millis. dstOffset = zone.getOffset(1, packed_date >> 9, (packed_date >> 5) & 15, packed_date & 31, day_field, millisInDay) - rawOffset; dstSet = true; // Adjust our millisInDay for DST, if necessary.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -