Calendar of java class source code and date Tools

Calendar of java class source code and date Tools

Calendar class definition

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {

    public final static int ERA = 0;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * year. This is a calendar-specific value; see subclass documentation.
     */
    public final static int YEAR = 1;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * month. This is a calendar-specific value. The first month of
     * the year in the Gregorian and Julian calendars is
     * <code>JANUARY</code> which is 0; the last depends on the number
     * of months in a year.
     *
     * @see #JANUARY
     * @see #FEBRUARY
     * @see #MARCH
     * @see #APRIL
     * @see #MAY
     * @see #JUNE
     * @see #JULY
     * @see #AUGUST
     * @see #SEPTEMBER
     * @see #OCTOBER
     * @see #NOVEMBER
     * @see #DECEMBER
     * @see #UNDECIMBER
     */
    public final static int MONTH = 2;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * week number within the current year.  The first week of the year, as
     * defined by <code>getFirstDayOfWeek()</code> and
     * <code>getMinimalDaysInFirstWeek()</code>, has value 1.  Subclasses define
     * the value of <code>WEEK_OF_YEAR</code> for days before the first week of
     * the year.
     *
     * @see #getFirstDayOfWeek
     * @see #getMinimalDaysInFirstWeek
     */
    public final static int WEEK_OF_YEAR = 3;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * week number within the current month.  The first week of the month, as
     * defined by <code>getFirstDayOfWeek()</code> and
     * <code>getMinimalDaysInFirstWeek()</code>, has value 1.  Subclasses define
     * the value of <code>WEEK_OF_MONTH</code> for days before the first week of
     * the month.
     *
     * @see #getFirstDayOfWeek
     * @see #getMinimalDaysInFirstWeek
     */
    public final static int WEEK_OF_MONTH = 4;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
     * The first day of the month has value 1.
     *
     * @see #DAY_OF_MONTH
     */
    public final static int DATE = 5;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * day of the month. This is a synonym for <code>DATE</code>.
     * The first day of the month has value 1.
     *
     * @see #DATE
     */
    public final static int DAY_OF_MONTH = 5;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the day
     * number within the current year.  The first day of the year has value 1.
     */
    public final static int DAY_OF_YEAR = 6;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the day
     * of the week.  This field takes values <code>SUNDAY</code>,
     * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
     * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>.
     *
     * @see #SUNDAY
     * @see #MONDAY
     * @see #TUESDAY
     * @see #WEDNESDAY
     * @see #THURSDAY
     * @see #FRIDAY
     * @see #SATURDAY
     */
    public final static int DAY_OF_WEEK = 7;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * ordinal number of the day of the week within the current month. Together
     * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
     * within a month.  Unlike <code>WEEK_OF_MONTH</code> and
     * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on
     * <code>getFirstDayOfWeek()</code> or
     * <code>getMinimalDaysInFirstWeek()</code>.  <code>DAY_OF_MONTH 1</code>
     * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
     * 1</code>; <code>8</code> through <code>14</code> correspond to
     * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
     * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
     * <code>DAY_OF_WEEK_IN_MONTH 1</code>.  Negative values count back from the
     * end of the month, so the last Sunday of a month is specified as
     * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>.  Because
     * negative values count backward they will usually be aligned differently
     * within the month than positive values.  For example, if a month has 31
     * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
     * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
     *
     * @see #DAY_OF_WEEK
     * @see #WEEK_OF_MONTH
     */
    public final static int DAY_OF_WEEK_IN_MONTH = 8;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating
     * whether the <code>HOUR</code> is before or after noon.
     * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
     *
     * @see #AM
     * @see #PM
     * @see #HOUR
     */
    public final static int AM_PM = 9;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * hour of the morning or afternoon. <code>HOUR</code> is used for the
     * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12.
     * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
     *
     * @see #AM_PM
     * @see #HOUR_OF_DAY
     */
    public final static int HOUR = 10;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
     * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
     *
     * @see #HOUR
     */
    public final static int HOUR_OF_DAY = 11;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * minute within the hour.
     * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
     */
    public final static int MINUTE = 12;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * second within the minute.
     * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
     */
    public final static int SECOND = 13;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * millisecond within the second.
     * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
     */
    public final static int MILLISECOND = 14;

  @SuppressWarnings("ProtectedField")
    protected int           fields[];

    @SuppressWarnings("ProtectedField")
    protected boolean       isSet[];

    transient private int   stamp[];

    @SuppressWarnings("ProtectedField")
    protected long          time;

    @SuppressWarnings("ProtectedField")
    protected boolean       isTimeSet;

    @SuppressWarnings("ProtectedField")
    protected boolean       areFieldsSet;

    transient boolean       areAllFieldsSet;

    private boolean         lenient = true;

    private TimeZone        zone;

    transient private boolean sharedZone = false;

    private int             firstDayOfWeek;

    private int             minimalDaysInFirstWeek;

    private static final ConcurrentMap<Locale, int[]> cachedLocaleData
        = new ConcurrentHashMap<>(3);

    protected Calendar()
    {
        this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
        sharedZone = true;
    }

    protected Calendar(TimeZone zone, Locale aLocale)
    {
        fields = new int[FIELD_COUNT];
        isSet = new boolean[FIELD_COUNT];
        stamp = new int[FIELD_COUNT];

        this.zone = zone;
        setWeekCountData(aLocale);
    }

    public static Calendar getInstance()
    {
        return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
    }

    public static Calendar getInstance(TimeZone zone)
    {
        return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT));
    }

    public static Calendar getInstance(Locale aLocale)
    {
        return createCalendar(TimeZone.getDefault(), aLocale);
    }

    public static Calendar getInstance(TimeZone zone,
                                       Locale aLocale)
    {
        return createCalendar(zone, aLocale);
    }

    private static Calendar createCalendar(TimeZone zone,
                                           Locale aLocale)
    {
        CalendarProvider provider =
            LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
                                 .getCalendarProvider();
        if (provider != null) {
            try {
                return provider.getInstance(zone, aLocale);
            } catch (IllegalArgumentException iae) {
                // fall back to the default instantiation
            }
        }

        Calendar cal = null;

        if (aLocale.hasExtensions()) {
            String caltype = aLocale.getUnicodeLocaleType("ca");
            if (caltype != null) {
                switch (caltype) {
                case "buddhist":
                cal = new BuddhistCalendar(zone, aLocale);
                    break;
                case "japanese":
                    cal = new JapaneseImperialCalendar(zone, aLocale);
                    break;
                case "gregory":
                    cal = new GregorianCalendar(zone, aLocale);
                    break;
                }
            }
        }
        if (cal == null) {
            // If no known calendar type is explicitly specified,
            // perform the traditional way to create a Calendar:
            // create a BuddhistCalendar for th_TH locale,
            // a JapaneseImperialCalendar for ja_JP_JP locale, or
            // a GregorianCalendar for any other locales.
            // NOTE: The language, country and variant strings are interned.
            if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
                cal = new BuddhistCalendar(zone, aLocale);
            } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
                       && aLocale.getCountry() == "JP") {
                cal = new JapaneseImperialCalendar(zone, aLocale);
            } else {
                cal = new GregorianCalendar(zone, aLocale);
            }
        }
        return cal;
    }

    public static synchronized Locale[] getAvailableLocales()
    {
        return DateFormat.getAvailableLocales();
    }

    protected abstract void computeTime();

    protected abstract void computeFields();

    public final Date getTime() {
        return new Date(getTimeInMillis());
    }

    public final void setTime(Date date) {
        setTimeInMillis(date.getTime());
    }

    public long getTimeInMillis() {
        if (!isTimeSet) {
            updateTime();
        }
        return time;
    }

    public void setTimeInMillis(long millis) {
        // If we don't need to recalculate the calendar field values,
        // do nothing.
        if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet
            && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) {
            return;
        }
        time = millis;
        isTimeSet = true;
        areFieldsSet = false;
        computeFields();
        areAllFieldsSet = areFieldsSet = true;
    }

    public int get(int field)
    {
        complete();
        return internalGet(field);
    }

    protected final int internalGet(int field)
    {
        return fields[field];
    }

    final void internalSet(int field, int value)
    {
        fields[field] = value;
    }

    public void set(int field, int value)
    {
        // If the fields are partially normalized, calculate all the
        // fields before changing any fields.
        if (areFieldsSet && !areAllFieldsSet) {
            computeFields();
        }
        internalSet(field, value);
        isTimeSet = false;
        areFieldsSet = false;
        isSet[field] = true;
        stamp[field] = nextStamp++;
        if (nextStamp == Integer.MAX_VALUE) {
            adjustStamp();
        }
    }
 
    public final void set(int year, int month, int date)
    {
        set(YEAR, year);
        set(MONTH, month);
        set(DATE, date);
    }

    public final void set(int year, int month, int date, int hourOfDay, int minute)
    {
        set(YEAR, year);
        set(MONTH, month);
        set(DATE, date);
        set(HOUR_OF_DAY, hourOfDay);
        set(MINUTE, minute);
    }

    public final void set(int year, int month, int date, int hourOfDay, int minute,
                          int second)
    {
        set(YEAR, year);
        set(MONTH, month);
        set(DATE, date);
        set(HOUR_OF_DAY, hourOfDay);
        set(MINUTE, minute);
        set(SECOND, second);
    }

    public final void clear()
    {
        for (int i = 0; i < fields.length; ) {
            stamp[i] = fields[i] = 0; // UNSET == 0
            isSet[i++] = false;
        }
        areAllFieldsSet = areFieldsSet = false;
        isTimeSet = false;
    }

    public final void clear(int field)
    {
        fields[field] = 0;
        stamp[field] = UNSET;
        isSet[field] = false;

        areAllFieldsSet = areFieldsSet = false;
        isTimeSet = false;
    }

    public final boolean isSet(int field)
    {
        return stamp[field] != UNSET;
    }

   @Override
    public String toString() {
        // NOTE: BuddhistCalendar.toString() interprets the string
        // produced by this method so that the Gregorian year number
        // is substituted by its B.E. year value. It relies on
        // "...,YEAR=<year>,..." or "...,YEAR=?,...".
        StringBuilder buffer = new StringBuilder(800);
        buffer.append(getClass().getName()).append('[');
        appendValue(buffer, "time", isTimeSet, time);
        buffer.append(",areFieldsSet=").append(areFieldsSet);
        buffer.append(",areAllFieldsSet=").append(areAllFieldsSet);
        buffer.append(",lenient=").append(lenient);
        buffer.append(",zone=").append(zone);
        appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek);
        appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek);
        for (int i = 0; i < FIELD_COUNT; ++i) {
            buffer.append(',');
            appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]);
        }
        buffer.append(']');
        return buffer.toString();
    }

    // =======================privates===============================

    private static void appendValue(StringBuilder sb, String item, boolean valid, long value) {
        sb.append(item).append('=');
        if (valid) {
            sb.append(value);
        } else {
            sb.append('?');
        }
    }

    private void setWeekCountData(Locale desiredLocale)
    {
        /* try to get the Locale data from the cache */
        int[] data = cachedLocaleData.get(desiredLocale);
        if (data == null) {  /* cache miss */
            data = new int[2];
            data[0] = CalendarDataUtility.retrieveFirstDayOfWeek(desiredLocale);
            data[1] = CalendarDataUtility.retrieveMinimalDaysInFirstWeek(desiredLocale);
            cachedLocaleData.putIfAbsent(desiredLocale, data);
        }
        firstDayOfWeek = data[0];
        minimalDaysInFirstWeek = data[1];
    }

    private void updateTime() {
        computeTime();
        // The areFieldsSet and areAllFieldsSet values are no longer
        // controlled here (as of 1.5).
        isTimeSet = true;
    }

    private int compareTo(long t) {
        long thisTime = getMillisOf(this);
        return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
    }

    private static long getMillisOf(Calendar calendar) {
        if (calendar.isTimeSet) {
            return calendar.time;
        }
        Calendar cal = (Calendar) calendar.clone();
        cal.setLenient(true);
        return cal.getTimeInMillis();
    }

    private void adjustStamp() {
        int max = MINIMUM_USER_STAMP;
        int newStamp = MINIMUM_USER_STAMP;

        for (;;) {
            int min = Integer.MAX_VALUE;
            for (int i = 0; i < stamp.length; i++) {
                int v = stamp[i];
                if (v >= newStamp && min > v) {
                    min = v;
                }
                if (max < v) {
                    max = v;
                }
            }
            if (max != min && min == Integer.MAX_VALUE) {
                break;
            }
            for (int i = 0; i < stamp.length; i++) {
                if (stamp[i] == min) {
                    stamp[i] = newStamp;
                }
            }
            newStamp++;
            if (min == max) {
                break;
            }
        }
        nextStamp = newStamp;
    }

    private void invalidateWeekFields()
    {
        if (stamp[WEEK_OF_MONTH] != COMPUTED &&
            stamp[WEEK_OF_YEAR] != COMPUTED) {
            return;
        }

        // We have to check the new values of these fields after changing
        // firstDayOfWeek and/or minimalDaysInFirstWeek. If the field values
        // have been changed, then set the new values. (4822110)
        Calendar cal = (Calendar) clone();
        cal.setLenient(true);
        cal.clear(WEEK_OF_MONTH);
        cal.clear(WEEK_OF_YEAR);

        if (stamp[WEEK_OF_MONTH] == COMPUTED) {
            int weekOfMonth = cal.get(WEEK_OF_MONTH);
            if (fields[WEEK_OF_MONTH] != weekOfMonth) {
                fields[WEEK_OF_MONTH] = weekOfMonth;
            }
        }

        if (stamp[WEEK_OF_YEAR] == COMPUTED) {
            int weekOfYear = cal.get(WEEK_OF_YEAR);
            if (fields[WEEK_OF_YEAR] != weekOfYear) {
                fields[WEEK_OF_YEAR] = weekOfYear;
            }
        }
    }

    private synchronized void writeObject(ObjectOutputStream stream)
         throws IOException
    {
        // Try to compute the time correctly, for the future (stream
        // version 2) in which we don't write out fields[] or isSet[].
        if (!isTimeSet) {
            try {
                updateTime();
            }
            catch (IllegalArgumentException e) {}
        }

        // If this Calendar has a ZoneInfo, save it and set a
        // SimpleTimeZone equivalent (as a single DST schedule) for
        // backward compatibility.
        TimeZone savedZone = null;
        if (zone instanceof ZoneInfo) {
            SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance();
            if (stz == null) {
                stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID());
            }
            savedZone = zone;
            zone = stz;
        }

        // Write out the 1.1 FCS object.
        stream.defaultWriteObject();

        // Write out the ZoneInfo object
        // 4802409: we write out even if it is null, a temporary workaround
        // the real fix for bug 4844924 in corba-iiop
        stream.writeObject(savedZone);
        if (savedZone != null) {
            zone = savedZone;
        }
    }

    private static class CalendarAccessControlContext {
        private static final AccessControlContext INSTANCE;
        static {
            RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar");
            PermissionCollection perms = perm.newPermissionCollection();
            perms.add(perm);
            INSTANCE = new AccessControlContext(new ProtectionDomain[] {
                                                    new ProtectionDomain(null, perms)
                                                });
        }
        private CalendarAccessControlContext() {
        }
    }

    /**
     * Reconstitutes this object from a stream (i.e., deserialize it).
     */
    private void readObject(ObjectInputStream stream)
         throws IOException, ClassNotFoundException
    {
        final ObjectInputStream input = stream;
        input.defaultReadObject();

        stamp = new int[FIELD_COUNT];

        // Starting with version 2 (not implemented yet), we expect that
        // fields[], isSet[], isTimeSet, and areFieldsSet may not be
        // streamed out anymore.  We expect 'time' to be correct.
        if (serialVersionOnStream >= 2)
        {
            isTimeSet = true;
            if (fields == null) {
                fields = new int[FIELD_COUNT];
            }
            if (isSet == null) {
                isSet = new boolean[FIELD_COUNT];
            }
        }
        else if (serialVersionOnStream >= 0)
        {
            for (int i=0; i<FIELD_COUNT; ++i) {
                stamp[i] = isSet[i] ? COMPUTED : UNSET;
            }
        }

        serialVersionOnStream = currentSerialVersion;

        // If there's a ZoneInfo object, use it for zone.
        ZoneInfo zi = null;
        try {
            zi = AccessController.doPrivileged(
                    new PrivilegedExceptionAction<ZoneInfo>() {
                        @Override
                        public ZoneInfo run() throws Exception {
                            return (ZoneInfo) input.readObject();
                        }
                    },
                    CalendarAccessControlContext.INSTANCE);
        } catch (PrivilegedActionException pae) {
            Exception e = pae.getException();
            if (!(e instanceof OptionalDataException)) {
                if (e instanceof RuntimeException) {
                    throw (RuntimeException) e;
                } else if (e instanceof IOException) {
                    throw (IOException) e;
                } else if (e instanceof ClassNotFoundException) {
                    throw (ClassNotFoundException) e;
                }
                throw new RuntimeException(e);
            }
        }
        if (zi != null) {
            zone = zi;
        }

        // If the deserialized object has a SimpleTimeZone, try to
        // replace it with a ZoneInfo equivalent (as of 1.4) in order
        // to be compatible with the SimpleTimeZone-based
        // implementation as much as possible.
        if (zone instanceof SimpleTimeZone) {
            String id = zone.getID();
            TimeZone tz = TimeZone.getTimeZone(id);
            if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) {
                zone = tz;
            }
        }
    }

    public final Instant toInstant() {
        return Instant.ofEpochMilli(getTimeInMillis());
    }
}

Java is recommended to replace the use of official use Date Calendar.

Free to convert between Calendar and Date, the conversion of bonds is time.

Calendar using the getTime () method can be an object of type Date, Date object underlying the use of the second-type parameter to the constructor Long created, the parameters are stored in a Long Calendar value in the time field, this time the value of the field is defined in a specific category assignment.

Implemented in such computeTime GregorianCalendar (), the purpose of this method is to convert the value to a time value field, the two modes relates to the Calendar, it will be introduced later.

And you can convert setTime (Date date) a method of Calendar Date object to a Calendar object, this method a Date object as a parameter, setTimeInMillis (long millis) method underlying call will date.getTime () as a parameter value , then this will be the bottom of a Long time parameter value is assigned to the field, then will re-calculated field value.

Calendar and Date of conversion:

public class CalendarTest {
    public static void main(String[] args) {
        //Calendar--->Date
        Calendar c = Calendar.getInstance();
        Date d = c.getTime();
        //Date--->Calendar
        Date d1 = new Date();
        Calendar c1 = Calendar.getInstance();
        c1.setTime(d1);
        
        System.out.println(d);
        System.out.println(c1.get(Calendar.YEAR)+"年"+(c1.get(Calendar.MONTH)+1)+"月"+c1.get(Calendar.DATE)+"日");
    }
}

Calendar of time and field

Calendar There are two time domain description of the contents, one is time, it is used to save a point in time Calendar object represents the number of milliseconds, according to January 1, 1970 00:00:00, and the other is the field, it is an array, it is not a representation of the content, but Calendar internally defined maximum static constant field.

Under normal circumstances but which are synchronized, that expressed the same point in time, but it is also possible without synchronization occurs:

  1. At first, field is not set, time is invalid
  2. If the time is set, all of the field is automatically set to the synchronization point of time
  3. If a field is provided separately, time will automatically expire

Rather, when we get a new Calendar object by Calendar.getInstance () method, it represents a point in time is set by time, and this is the value of time by System.currentTimeMillis () get, by the time defined Calendar, isTimeSet is true, that is the latest time value (true), areFieldsSet to false, indicating the value field field are old (false), because when we re-set the time value, Calendar of the it represents the point in time of changes (here for the first time, the equivalent of from scratch, can be considered a change, and then when we re-time Calendar set a new value, Calendar point in time will change again, it will point to point in time the latest time value represents), but this time in the field also represents the original point of time, and then calls computeFields () method to re-calculate the values ​​of all fields to ensure that the value of the time field synchronization and at the same time areFieldsSet and areAllFieldsSet set to true, it indicates the time value of all field representatives is the latest of the (true). In fact, every time we change the time value will automatically trigger recalculation, to ensure a consistent point in time the two domains are described (ie synchronous), which is the content of the above b.

But if we field a row in a field to make changes individually by set (int field, int value), will first trigger a verification, areFieldsSet true and areAllFieldsSet is false, indicating that only a portion of field is the latest situation, that is, there is part of the field belonging to the old situation, this situation triggers a recalculation of the field; then will isTimeSet set to false, areFieldsSet set to false, the isSet [field] is set to true (the current field is set to true), which under case, when we use the getTime () Gets the point in time time value represents the time since isTimeSet false, the trigger time of recalculation, the basis for calculation is carried out based on the value field, and after isTimeSet set to true, Similarly, we will verify whether isTimeSet is true, if false, it will also trigger a recalculation time, and then verify areFieldsSet is false, re-calculate the remaining field is triggered when obtaining a field value by get (int field).

Weight calculation time is based on the field, precisely, is the basis for part of the field, and the field is part of the field on the basis of re-calculated, it can be said that there is a fixed part of the field, and time is closely related.

All these are the rules for implementing the entire interior of the Calendar, Externally, we can simply call, all of which are hidden inside, so as to ensure that the correct value of our direct acquired through external methods.

public class CalendarTest {
    public static void main(String[] args) throws ParseException {
        System.out.println("-------初始情况-------");
        Calendar c = Calendar.getInstance();
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DATE));
        System.out.println(c.get(Calendar.HOUR));
        System.out.println("-------重设置time-------");
        c.setTime(new SimpleDateFormat("yyyyMMdd").parse("20170501"));
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DATE));
        System.out.println(c.get(Calendar.HOUR));
        System.out.println("-------重设置field-------");
        c.set(Calendar.MONTH, 4);
        System.out.println(c.getTime());
        System.out.println(c.get(Calendar.DATE));
        System.out.println(c.get(Calendar.HOUR));
        System.out.println("总结:time与field所代表时间点同步,所有的不同步全部在内部处理完成");
    }
}

Results of the:

-------初始情况-------
Sat Jul 08 13:08:34 CST 2017
8
1
-------重设置time-------
Mon May 01 00:00:00 CST 2017
1
0
-------重设置field-------
Mon May 01 00:00:00 CST 2017
1
0
总结:time与field所代表时间点同步,所有的不同步全部在内部处理完成

Calendar of two analytical models

  • lenient: In this mode the user may be automatically assigned to regularize irregular Calendar value, such as January 32 resolves to February 1
  • non-lenient: not automatically parse the input of the irregular pattern, but irregular Once input, the abnormality will be reported

This is also called Calendar of fault tolerance, opening and closing use setLenient (boolean lenient) method to set the lenient, true indicate on fault tolerance (default), false representation disable this feature.

Example:

public class CalendarTest {
    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.MONTH, 8);
        c.set(Calendar.DAY_OF_MONTH, 33);
        System.out.println(c.getTime()+"\n");
        c.setLenient(false);
        c.set(Calendar.MONTH, 8);
        c.set(Calendar.DAY_OF_MONTH, 33);
        System.out.println(c.getTime());
    }
}

Results of the:

Tue Oct 03 13:18:48 CST 2017

Exception in thread "main" java.lang.IllegalArgumentException: DAY_OF_MONTH
    at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2583)
    at java.util.Calendar.updateTime(Calendar.java:2606)
    at java.util.Calendar.getTimeInMillis(Calendar.java:1118)
    at java.util.Calendar.getTime(Calendar.java:1091)
    at JdkTest.main(JdkTest.java:87)

As can be seen from the above example, by default, we assign Calendar for the month of September 8 that is, the date that is assigned to No. 333 next month, the output for the October 3, fault tolerance will not comply with this enter the rule of rules to deal with, but after closing fault tolerance, the same assignment only reported abnormal java.lang.IllegalArgumentException (illegal argument exception).

Calendar of use

Example:

public class CalendarTest {
    public static void main(String[] args) throws ParseException {
        //通过SimpleDateFormat解析日期字符串
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss.SSS");
        Date date = sdf.parse("20170502 13:33:23.433");
        //将Date格式日期转换成Calendar
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        //获取时间值
        System.out.println(c.getTime());
        System.out.println("年份为"+c.get(Calendar.YEAR));
        System.out.println("月份为"+c.get(Calendar.MONTH));
        System.out.println("日期为"+c.get(Calendar.DATE));
        System.out.println("日期为"+c.get(Calendar.DAY_OF_MONTH));
        System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK));
        System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK_IN_MONTH));
        System.out.println("日期为"+c.get(Calendar.DAY_OF_YEAR));
        System.out.println("时为"+c.get(Calendar.HOUR));
        System.out.println("时为"+c.get(Calendar.HOUR_OF_DAY));
        System.out.println("分为"+c.get(Calendar.MINUTE));
        System.out.println("秒为"+c.get(Calendar.SECOND));
        System.out.println("毫秒为"+c.get(Calendar.MILLISECOND));
        System.out.println("星期为"+c.get(Calendar.WEEK_OF_MONTH));
        System.out.println("星期为"+c.get(Calendar.WEEK_OF_YEAR));
        System.out.println("历型为"+c.get(Calendar.ERA));
        System.out.println("zone为"+c.get(Calendar.ZONE_OFFSET));
        //设置
        c.set(Calendar.MONTH, Calendar.APRIL);
        System.out.println("修改后月份为"+c.get(Calendar.MONTH));
        c.set(1999, 0, 23);
        System.out.println(c.getTime());
        c.set(2000, 1, 12, 13, 33, 14);
        System.out.println(c.getTime());
        c.set(2001, 2, 13, 14, 13);
        System.out.println(c.getTime());
        //运算
        System.out.println("-----运算-----");
        c.add(Calendar.YEAR, 12);
        System.out.println(c.getTime());
        c.add(Calendar.MONTH, -1);
        System.out.println(c.getTime());
        c.roll(Calendar.DATE, true);
        System.out.println(c.getTime());
        c.add(Calendar.DATE, 1);
        System.out.println(c.getTime());
        //roll与add运算对比
        c.set(2000, 1, 29);
        System.out.println(c.getTime());
        c.roll(Calendar.DATE, 1);
        System.out.println(c.getTime());
        c.set(2000, 1, 29);
        c.add(Calendar.DATE, 1);
        System.out.println(c.getTime());
    }
}

Implementation of the results:

Tue May 02 13:33:23 CST 2017
年份为2017
月份为4
日期为2
日期为2
日期为3
日期为1
日期为122
时为1
时为13
分为33
秒为23
毫秒为433
星期为1
星期为18
历型为1
zone为28800000
修改后月份为3
Sat Jan 23 13:33:23 CST 1999
Sat Feb 12 13:33:14 CST 2000
Tue Mar 13 14:13:14 CST 2001
-----运算-----
Wed Mar 13 14:13:14 CST 2013
Wed Feb 13 14:13:14 CST 2013
Thu Feb 14 14:13:14 CST 2013
Fri Feb 15 14:13:14 CST 2013
Tue Feb 29 14:13:14 CST 2000
Tue Feb 01 14:13:14 CST 2000
Wed Mar 01 14:13:14 CST 2000

The last two lines of the above comparison output, it can be seen to change the rules of operation add and roll is actually different, roll the operation will not affect the big rule (big rule here refers to the change in the month), which will add impact.

 

 

 

 

 

Published 370 original articles · won praise 88 · views 290 000 +

Guess you like

Origin blog.csdn.net/qq_35029061/article/details/100523688