1. Overview of Calendar
Java officially recommends using Calendar to replace the use of Date. Calendar and Date can be converted freely. The link of conversion is time. Use Calendar’s getTime() The method can get a Date type object. The bottom layer of this object is created using the second constructor of Date with a Long type parameter. This Long type parameter is the value saved in the time field in Calendar. The value of this time field is The assignment is defined in a specific implementation class, such as the implementation of computeTime() in GregorianCalendar. The purpose of this method is to convert the field value into a time value. This involves two modes in Calendar, which will be introduced later; and through Calendar The setTime(Date date) method can convert a Date object into a Calendar object. This method takes a Date object as a parameter. The setTimeInMillis(long millis) method called by the bottom layer takes the value of date.getTime() as a parameter. The bottom layer will Assign this Long parameter value to the time field, and the field value will be recalculated.
Conversion between Calendar and Date
1 public static void main(String[] args) { 2 //Calendar--->Date 3 Calendar c = Calendar.getInstance(); 4 Date d = c.getTime(); 5 //Date--->Calendar 6 Date d1 = new Date(); 7 Calendar c1 = Calendar.getInstance(); 8 c1.setTime(d1); 9 10 System.out.println(d);11 System.out.println(c1.get(Calendar.YEAR)+"年"+(c1.get(Calendar.MONTH)+1)+"月"+c1.get(Calendar.DATE)+"日");12 }
Result:
Sat Jul 08 10:39:14 CST 20172017年7月8日
2. Time and field in Calendar
There are two fields in Calendar that describe time content. One is time, which is used to save the number of milliseconds at the time point represented by the Calendar object as of 00:00:00 on January 1, 1970. The other is field, it is an array, it does not represent a content, but the most static constant fields defined within Calendar.
This is generally synchronous, that is, it expresses the same point in time, but it may also be out of sync:
a. Initially, the field is not set and the time is invalid. ’s
b. If time is set, all fields will automatically be set to the synchronized time point
c. If a certain field is set individually, time will automatically expire
To be more precise, when we obtain a new Calendar object through the Calendar.getInstance() method, the time point it represents is set through time, and the value of this time is obtained through System.currentTimeMillis() Define Calendar through time. isTimeSet is true, which means that the time value is the latest (true), and areFieldsSet is false, which means that the values of the field fields are all old (false), because when we reset the time value, The time point represented by Calendar has changed (this is the first time, which is equivalent to starting from scratch, which is also a change. Later, when we reset a new value for Calendar's time, Calendar's time point will change again. It will point to the time point represented by the latest time value), and at this time the field still represents the original time point content, and then the computeFields() method will be called to recalculate all field values to ensure that the values in the field are consistent with Time is synchronized, and areFieldsSet and areAllFieldsSet are set to true at the same time, indicating that the time values represented by all fields are also the latest (true). In fact, every time we change the time value, it will automatically trigger a recalculation to ensure that the time points described by the two domains are consistent (that is, synchronized), which is what is described in b above.
But if we use set(int field, int value) to individually change a field in a row in the field, a verification will be triggered first. When areFieldsSet is true and areAllFieldsSet is false, it means that only part of the field is is the latest situation, that is, some fields are old. In this case, a recalculation of the fields will be triggered; after that, isTimeSet will be set to false, areFieldsSet will be set to false, and isSet[field] will be set to true (the current field set to true), in this case, when we use getTime() to obtain the time point represented by the time value, since isTimeSet is false, a recalculation of time will be triggered. This calculation is based on the value of the field. After that Set isTimeSet to true. Similarly, when we obtain a field value through get(int field), we will first verify whether isTimeSet is true. If it is false, it will also trigger the recalculation of time, and then verify that areFieldsSet is false, then trigger Recalculation of remaining fields.
The recalculation of time is based on fields. To be precise, it is based on part of fields. Some fields are also recalculated on the basis of fields. Therefore, it can be said that some fields are fixed and are equal to Time is closely related,
All of the above are the internal implementation rules of Calendar. Externally, we only need simple calls, all of which are hidden internally, ensuring that we obtain them through external methods. The correct value is obtained directly.
1 public static void main(String[] args) throws ParseException { 2 System.out.println("-------初始情况-------"); 3 Calendar c = Calendar.getInstance(); 4 System.out.println(c.getTime()); 5 System.out.println(c.get(Calendar.DATE)); 6 System.out.println(c.get(Calendar.HOUR)); 7 System.out.println("-------重设置time-------"); 8 c.setTime(new SimpleDateFormat("yyyyMMdd").parse("20170501")); 9 System.out.println(c.getTime());10 System.out.println(c.get(Calendar.DATE));11 System.out.println(c.get(Calendar.HOUR));12 System.out.println("-------重设置field-------");13 c.set(Calendar.MONTH, 4);14 System.out.println(c.getTime());15 System.out.println(c.get(Calendar.DATE));16 System.out.println(c.get(Calendar.HOUR));17 System.out.println("总结:time与field所代表时间点同步,所有的不同步全部在内部处理完成");18 }
Result:
-------初始情况-------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所代表时间点同步,所有的不同步全部在内部处理完成
3. Two parsing modes in Calendar
Lenient: This mode can automatically Regularize the irregular values assigned by users to Calendar. For example, January 32 will be parsed as February 1
Non-lenient: In this mode, irregular input will not be automatically parsed, but once discovered Irregular input will result in an exception
This is also called the fault tolerance of Calendar. The turning on and off of lenient is set using the setLenient(boolean lenient) method. true means turning on fault tolerance (default), false means Turn off this feature.
1 public static void main(String[] args) { 2 Calendar c = Calendar.getInstance(); 3 c.set(Calendar.MONTH, 8); 4 c.set(Calendar.DAY_OF_MONTH, 33); 5 System.out.println(c.getTime()+"\n"); 6 c.setLenient(false); 7 c.set(Calendar.MONTH, 8); 8 c.set(Calendar.DAY_OF_MONTH, 33); 9 System.out.println(c.getTime());10 }
结果:
Tue Oct 03 13:18:48 CST 2017Exception 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)
从上面的例子中可以看出,默认情况下,我们为Calendar的月份赋值为8即九月份,日期赋值为33即下一月3号,输出为10月3日,容错性将这种不符合规则的输入规则化处理了,而关闭容错性之后,同样的赋值只会报异常java.lang.IllegalArgumentException(非法参数异常)。
4、Calendar的使用
1 public static void main(String[] args) throws ParseException { 2 //通过SimpleDateFormat解析日期字符串 3 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd hh:mm:ss.SSS"); 4 Date date = sdf.parse("20170502 13:33:23.433"); 5 //将Date格式日期转换成Calendar 6 Calendar c = Calendar.getInstance(); 7 c.setTime(date); 8 //获取时间值 9 System.out.println(c.getTime());10 System.out.println("年份为"+c.get(Calendar.YEAR));11 System.out.println("月份为"+c.get(Calendar.MONTH));12 System.out.println("日期为"+c.get(Calendar.DATE));13 System.out.println("日期为"+c.get(Calendar.DAY_OF_MONTH));14 System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK));15 System.out.println("日期为"+c.get(Calendar.DAY_OF_WEEK_IN_MONTH));16 System.out.println("日期为"+c.get(Calendar.DAY_OF_YEAR));17 System.out.println("时为"+c.get(Calendar.HOUR));18 System.out.println("时为"+c.get(Calendar.HOUR_OF_DAY));19 System.out.println("分为"+c.get(Calendar.MINUTE));20 System.out.println("秒为"+c.get(Calendar.SECOND));21 System.out.println("毫秒为"+c.get(Calendar.MILLISECOND));22 System.out.println("星期为"+c.get(Calendar.WEEK_OF_MONTH));23 System.out.println("星期为"+c.get(Calendar.WEEK_OF_YEAR));24 System.out.println("历型为"+c.get(Calendar.ERA));25 System.out.println("zone为"+c.get(Calendar.ZONE_OFFSET));26 //设置27 c.set(Calendar.MONTH, Calendar.APRIL);28 System.out.println("修改后月份为"+c.get(Calendar.MONTH));29 c.set(1999, 0, 23);30 System.out.println(c.getTime());31 c.set(2000, 1, 12, 13, 33, 14);32 System.out.println(c.getTime());33 c.set(2001, 2, 13, 14, 13);34 System.out.println(c.getTime());35 //运算36 System.out.println("-----运算-----");37 c.add(Calendar.YEAR, 12);38 System.out.println(c.getTime());39 c.add(Calendar.MONTH, -1);40 System.out.println(c.getTime());41 c.roll(Calendar.DATE, true);42 System.out.println(c.getTime());43 c.add(Calendar.DATE, 1);44 System.out.println(c.getTime());45 //roll与add运算对比46 c.set(2000, 1, 29);47 System.out.println(c.getTime());48 c.roll(Calendar.DATE, 1);49 System.out.println(c.getTime());50 c.set(2000, 1, 29);51 c.add(Calendar.DATE, 1);52 System.out.println(c.getTime());53 }
结果:
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 1999Sat Feb 12 13:33:14 CST 2000Tue Mar 13 14:13:14 CST 2001 -----运算-----Wed Mar 13 14:13:14 CST 2013Wed Feb 13 14:13:14 CST 2013Thu Feb 14 14:13:14 CST 2013Fri Feb 15 14:13:14 CST 2013Tue Feb 29 14:13:14 CST 2000Tue Feb 01 14:13:14 CST 2000Wed Mar 01 14:13:14 CST 2000
对比上面最后的两行输出,可以看出add与roll的运算规则其实是不同的,roll的运算不会影响大规则(这里的大规则指的是月份的改变)的改变,而add会影响。
The above is the detailed content of Overview of Calendar. For more information, please follow other related articles on the PHP Chinese website!