⛳️概述
Calendar类是一个抽象类,它为特定瞬间与一组例如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如从日历对象中获得本周是本月的第几周)提供了一些方法。
-
Calendar类是一个抽象类,所以我们要通过创建其子类的对象实现这个抽象类中的一些方法
-
在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。
⛳️日历类(Calender类)的实例化
方式一:
通过调用Calendar类中的getInstance()静态方法
-
通过调用Calendar类中的getInstance()静态方法就可以的得到一个GregorianCalendar类的对象
-
getInstance()方法返回值类型为GregorianCalendar
方式二:
直接创建其子类的对象 (也就是创建一个GregorianCalendar类的对象)
-
java中提供了Calender类的一个子类:GregorianCalendar
//方式①:创建子类对象,这个时候我们可以选择使用多态的语法,父类的引用指向子类的对象
Calendar c = Calendar.getInstance();
//方式②:获得日历对象,实现的是子类
Calendar c1 = new GregorianCalendar();
-
使用多态可以降低代码的耦合性(并且也可应直接使用子类重写的父类的方法)
那么我们如何知道Calendar.getInstance()方法是返回了GregorianCalendar类的对象?
可以通过使用我们getInstance()方法调用一个getClass()方法,然后再对这个方法的返回值进行输出
-
getClass();返回当前当前对象创建类的全类名
-
这里就是返回:class java.util.GregorianCalendar
-
通过这种方式的输出我们就可以发现Calendar类的getInstance()方法时返回了一个GregorianCalendar类的对象
-
⛳️常用成员方法
①static Calendar getInstance()
-
使用默认时区和区域设置获取日历,通过该方法生成Calendar对象。
-
Calendar cr=Calendar.getInstance();
②public int get()
-
获取我们一些常用的属性
eg: int days = cn.get(Calender.DAY_OF_MONTH);
这个方法的返回值就是这个cn对象所代表的日期是这个月的第几天
③public void set(int field,int value)
-
修改(设置)我们一些常用的属性
-
形参field就是我们想要修改的日历字段,value就是我们用来替换的值
-
这个方法是没有返回值的,就是在原本对象上进行了改变
-
④public void add(int field,int amount)
-
按照日历的规则,给指定字段添加或减少时间量。
-
通过amount变量的正负来控制是减还是加,如果是减的话就是这里的时间量是一个负数
-
形参field就是我们想要修改的日历字段,amount就是我们要增加或者减去的时间量
-
⑤public Date getTime()
-
返回一个Date表示此日历的时间。Calendar---->Date
-
该方法是无参的
-
⑥public void setTime(Date date)
-
使用给定的Date设置此日历的时间。Date---->Calendar
-
这里其实就是传入了一个Date对象,这个时候底层是调用了setTimeMillis()方法,设置了Calendar对象中的时间,这个时候Calendar对象对应的时间就变成了Date对象对应的时间
-
其实只是将我们的Calendar对象对应的时间修改成了和Date对象对应的时间相同的
-
在使用Calendar类获取月份时:一月是0、二月是1、三月是2…十二月是11
-
在我们使用Calendar类获取星期时:周日是1、周一是2、周二是3
-
⑦public long getTimeInMillis()
-
将日历类转化成了时间戳,以毫秒为单位返回该日历的时间值
-
我们可以再使用Date的构造方法将这个时间戳再转换为一个Date类型的对象
-
该方法是无参的,get()方法一般都是无参的
-
⛳️日历字段
日历字段包含以下两种:一种是表示时间的单位,例如年、月、日等等;另一种是具体的日期,例如一月、二月、三月、一日、二日、三日、一点钟、两点钟等等具体的时间。前一种一般时获取的时候使用,后一种一般判断的时候使用。
YEAR | 年 | DAY_OF_WEEK | 一周的第几天 |
---|---|---|---|
MONTH | 月 | DAY_OF_MONTH | 一月的第几天 |
DATE | 日 | DAY_OF_YEAR | 一年的第多少天 |
HOUR_OF_DAY | 时 | DAY_OF_WEEK_IN_MONTH | 某月中第几周 |
MINUTE | 分 | WEEK_OF_MONTH | 一月的第几周 |
SECOND | 秒 | WEEK_OF_YEAR | 一年的第多少周 |
MILLISECOND | 毫秒 | HOUR_OF_DAY | 一天的第几个小时 |
案例:
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class CalendarDemo {
public static void main(String[] args) {
/*
Calendar 是一个抽象类,抽象类不能创建对象,怎么表示一个时间?
Calendar.getInstance(); 获得是一个子类对象,GregorianCalendar 公历
*/
//方式①:Calendar c = Calendar.getInstance();
//方式②:获得日历对象 实现的是子类
Calendar c1 = new GregorianCalendar();
//从日历对象中获取今天是这个月中的第几天
System.out.println(c1.get(Calendar.DAY_OF_MONTH));//30
//从日历对象中获取今天是今年的第几天
System.out.println(c1.get(Calendar.DAY_OF_YEAR));//89
//从日历对象中获取本周是今年的第几周
System.out.println(c1.get(Calendar.WEEK_OF_YEAR));//14
//从日历对象中获取本周是本月的第几周
System.out.println(c1.get(Calendar.WEEK_OF_MONTH));//5
//从日历对象中获取今天是本周的第几天
System.out.println(c1.get(Calendar.DAY_OF_WEEK));//4
//从日历中获取现在是今天的第几个小时
System.out.println(c1.get(Calendar.HOUR_OF_DAY));//23
}
}
注意:month是从0开始的,而月份是从1开始的,所以month需要加1
⛳️Calendar类的缺点(所以后面又产生了java.time包)
1.可变性(Calendar类是可变的)
一般我们的日期时间对象一旦创建之后就不应该再进行修改,如果我们要修改就去创建一个新的对象(也就是类似于String一样具有不可变性)
2.不可以格式化(Calendar类是不可以进行格式化的)
3.线程不安全
Calender类是线程不安全的,无法处理闰秒的问题等
-
闰秒:当我们的世界时(民用时)和原子时相差±0.9秒时,我们就要把世界时(民用时)向前拨一秒 (负闰秒),或者向后拨一秒(正闰秒)
-
目前全球进行了27次闰秒(都是正闰秒)