In-depth discussion on the use of calendar. Set

Source: Internet
Author: User

Generally, the add method is used when calendar is used for date processing:

Calendar calendar = calendar. getinstance ();
Calendar. settime (date );
Calendar.Add(Calendar. Second, 1 );

 

When the latest code review, we can see that someone uses the Set Method for date processing:

Calendar calendar = calendar. getinstance ();
Calendar. settime (date );
Calendar. Set (calendar. Month, calendar. Get (calendar. month) + month );

 

As a result, he jumped out immediately and told him that he was wrong. Unfortunately, BS was immediately returned because he could see the following test code:

Calendar Cal = calendar. getinstance ();
Cal. Set (2009, 02, 15 );
Date testdate = Cal. gettime ();
System. Out. println (testdate );

Calendar calendar = calendar. getinstance ();
Calendar. settime (testdate );
Calendar. Set (calendar. Month, calendar. Get (calendar. month) + 1 );
Date testdate2 = calendar. gettime ();
System. Out. println (testdate2 );

Output result:

Sun Mar 11:21:18 CST 2009
Wed Apr 15 11:21:18 CST 2009

That is to say, the set method can also be used for field operations !!

 

Fortunately, I am a person who has the courage to admit mistakes. After apologizing, I was forgiven by the other party, but I still cannot accept this fact. JDK is also too earthy, is there no difference in designing these two methods? So what is the add method?

 

With the above problem in mind, I started code review again today. The more I think about it, the more I can't think of it. It's unreasonable. Forget it. Check the JDK documentation. Below is a comment on the calendar class in JDK:

 

 

You can change the calendar field in three ways:set(),add()Androll().

 

set(f, value)Set the calendar FieldfChangevalue. In addition, it sets an internal member variable to indicate the calendar FieldfIt has been changed. Despite calendar FieldsfIs changed immediately, but is not called until the next time.get(),getTime(),getTimeInMillis(),add()Orroll()The time value of the calendar (in milliseconds) is recalculated ). Therefore, multiple callsset()Does not trigger unnecessary computing multiple times. Useset()The result of changing the calendar field is that other calendar fields may also be changed, depending on the calendar field, calendar field value, and calendar system. In addition, after recalculating the calendar field,get(f)No need to callsetMethod returnvalueSet. The specific details are determined by the specific calendar class.

Example: AssumeGregorianCalendarIt was initially set to August 31, 1999. Callset(Calendar.MONTH, Calendar.SEPTEMBER)Set this date to January 1, September 31, 1999. If you callgetTime(), So this is a temporary internal representation for parsing in October 1, 1999. HowevergetTime()Previously calledset(Calendar.DAY_OF_MONTH, 30)This date is set to September 30, 1999, becauseset()No re-calculation occurred.

add(f, delta)SetdeltaAddfField. This is equivalent to callingset(f, get(f) + delta)But it must include the following two adjustments:

Add Rule 1. After the callfField Value minus before callfThe field value is equaldelta, With FieldsfAny overflow occurs as a model. Overflow occurs when the field value exceeds its range. As a result, the next larger field will increase or decrease progressively, and the field value will be adjusted back to its range.

Add Rule 2. It is impossible to expect a smaller field to remain unchanged but make it equal to the previous value, becausefAfter the change, or after other constraints, such as the time zone offset, the maximum and minimum values are also changed, then its value is adjusted to be as close as possible to the expected value. A smaller field indicates a smaller unit of time.HOURIs a ratioDAY_OF_MONTHSmall field. For smaller fields that do not expect to be unchanged, no adjustment is required. The calendar system determines the expected fields.

In additionset()Different,add()Force the calendar system to re-calculate the calendar's millisecond count and all fields immediately.

Example: AssumeGregorianCalendarIt was initially set to August 31, 1999. Calladd(Calendar.MONTH, 13)Set the calendar to September 30, 2000.Add Rule 1SetMONTHThe field is set to September, because the next year's September is obtained by adding 13 months to August. Because inGregorianCalendarMedium,DAY_OF_MONTHIt cannot be September 31, soAdd Rule 2SetDAY_OF_MONTHSet to 30, which is the most likely value. Although it is a smaller field, it cannot be adjusted according to Rule 2.DAY_OF_WEEKBecause inGregorianCalendarWhen the month in changes, the value also needs to change.

roll(f, delta)SetdeltaAddfField, but do not change the larger field. This is equivalent to callingadd(f, delta)But with the following adjustments:

Roll rule. After the call is completed, the larger field remains unchanged. A larger field indicates a larger unit of time.DAY_OF_MONTHIs a ratioHOURLarge field.

Example: SeeGregorianCalendar.roll(int, int).

Use Model. To help understandadd()Androll()Assume that there is a user interface component withGregorianCalendar. If the date read from the interface is January 1, January 31, 1999, and you press the incremental button of the month, what should you get? If the underlying implementation usesset()You can set the date to March 3, 1999. The better result is February 28, 1999. In addition, if you re-Press the incremental button of the month, the date should be read as January 1, March 31, 1999, rather than January 1, March 28, 1999. By saving the original date and usingadd()Orroll(), Depending on whether it will affect more fields, the user interface can run as expected by most users.

 

After carefully studying the above annotations, I finally found a trace of clues. The add method is different from the set method. It should be different in the natural day processing, so I have the following code:

Calendar Cal = calendar. getinstance ();
Cal. Set (2009, 02, 31 );
Date testdate = Cal. gettime ();
System. Out. println (testdate );

Calendar cal1 = calendar. getinstance ();
Cal1.settime (testdate );
Cal1.add (calendar. month, 1 );
Date testdate1 = cal1.gettime ();
System. Out. println (testdate1 );

The output is as follows:

Tue Mar 31 11:27:41 CST 2009
Thu Apr 30 11:27:41 CST 2009

 

OK. The conclusion is that the add method will process the increase or decrease of the calendar month to process the date part, but the set method will only be treated as 30 days. Facts have proved that the original feeling is correct. I hope that similar errors will not be encountered in the future !!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.