Java常用类源码分析_Calendar类

Calendar 类是一个抽象类,它为特定瞬间(瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。)与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段(日历字段是Calendar类特有的)之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public class Main {
    /** * @param args */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //java.util.Locale 对象表示了特定的地理、政治和文化地区。
        //需要 Locale 来执行其任务的操作称为语言环境敏感的 操作,它使用 Locale为用户量身定制信息。
        //例如,显示一个数值就是语言环境敏感的操作,应该根据用户的国家、地区或文化的风俗/传统来格式化该数值。


        //java.util.TimeZone 表示时区偏移量,也可以计算夏令时。
        //通常,使用 getDefault()获取 TimeZone,getDefault 基于程序运行所在的时区创建TimeZone。
        //例如,对于在日本运行的程序,getDefault()基于日本标准时间创建 TimeZone 对象。
        //也可以用 getTimeZone及时区 ID获取 TimeZone。例如美国太平洋时区的时区 ID是"America/Los_Angeles"。
        //因此,可以使用下面语句获得美国太平洋时间 TimeZone对象:
        TimeZone timezone1=TimeZone.getTimeZone("America/Los_Angeles");
        //使用 getAvailableIDs 方法来对所有受支持的时区 ID 进行迭代。
        String[] availableIDs=TimeZone.getAvailableIDs();
        for(int i=0;i<availableIDs.length;i++){
            System.out.println(availableIDs[i]);
        }


        //Calendar 提供了多个类方法 getInstance(),以获得此类型的一个通用的对象,
        //这些类方法根据TimeZone、Locale类来获取特定的Calendar,
        //如果不指定TimeZone、Locale,则使用默认的TimeZone、Locale来创建Calendar.
        //Calendar的 getInstance()方法返回一个 Calendar对象,其日历字段已由当前日期和时间(即计算机系统显示的当前日期和时间)初始化: 
        Calendar  calendar1= Calendar.getInstance();//返回的 Calendar 基于当前日期和时间,使用了默认时区和默认语言环境。
        Calendar  calendar2= Calendar.getInstance(Locale.JAPAN);//返回的 Calendar 基于当前日期和时间,使用了默认时区和给定语言环境(日本)。
        Calendar  calendar3= Calendar.getInstance(TimeZone.getTimeZone("America/Los_Angeles"));//返回的 Calendar 基于当前日期和时间,使用了给定时区(美国洛杉矶)和默认语言环境。
        Calendar  calendar4= Calendar.getInstance(TimeZone.getDefault(),Locale.getDefault());//返回的 Calendar 基于当前日期和时间,使用了给定时区和给定语言环境。但这里与第一个getInstance()返回的Calendar对象相同


        //Calendar与Date的自由转换
        Date date=calendar1.getTime();//返回一个表示此 Calendar时间值(从历元至现在的毫秒偏移量)的 Date对象
        calendar1.setTime(date);//使用给定的 Date设置此 Calendar的时间。因为Calendar没有构造函数可以接受Date对象,所以必须先获得一个Calendar实例,然后调用其setTime(Date date)方法 



        //Calendar类的常用日历字段
        //YEAR--->指示年的字段数字。
        //MONTH--->指示月份的字段数字。在格里高利历和罗马儒略历中一年中的第一个月是 JANUARY,它为 0。
        //DATE--->指示一个月中的某天。它与 DAY_OF_MONTH是同义词。一个月中第一天的值为 1。
        //DAY_OF_MONTH--->指示一个月中的某天。它与 DATE 是同义词。一个月中第一天的值为 1。
        //DAY_OF_YEAR--->指示当前年中的天数。一年中第一天的值为 1。
        //DAY_OF_WEEK--->指示一个星期中的某天。该字段可取的值为 SUNDAY、MONDAY、TUESDAY、WEDNESDAY、THURSDAY、FRIDAY和 SATURDAY。
        //AM_PM--->指示 HOUR 是在中午之前还是在中午之后。例如,在 10:04:15.250 PM 这一时刻,AM_PM 为 PM。 
        //HOUR--->指示上午或下午的小时。HOUR用于12小时制时钟 (0-11)。中午和午夜用 0表示,不用 12表示。例如,在 10:04:15.250 PM 这一时刻,HOUR 为 10。
        //HOUR_OF_DAY--->指示一天中的小时。HOUR_OF_DAY 用于 24 小时制时钟。例如,在 10:04:15.250 PM 这一时刻,HOUR_OF_DAY 为 22。
        //MINUTE--->指示一小时中的分钟。例如,在 10:04:15.250 PM 这一时刻,MINUTE 为 4。
        //SECOND--->指示一分钟中的秒。例如,在 10:04:15.250 PM 这一时刻,SECOND 为 15。
        //MILLISECOND--->指示一秒中的毫秒。例如,在 10:04:15.250 PM 这一时刻,MILLISECOND 为 250。
        //MONDAY--->指示 MONDAY 的 DAY_OF_WEEK 字段值
        //TUESDAY--->指示 TUESDAY 的 DAY_OF_WEEK 字段值
        //WEDNESDAY--->指示 WENDESDAY 的 DAY_OF_WEEK 字段值
        //THURSDAY--->指示 THURSDAY 的 DAY_OF_WEEK 字段值
        //FRIDAY--->指示 FRIDAY 的 DAY_OF_WEEK 字段值
        //SATURDAY--->指示 SATURDAY 的 DAY_OF_WEEK 字段值
        //SUNDAY--->指示 SUNDAY 的 DAY_OF_WEEK 字段值
        //JANUARY--->指示在格里高利历和罗马儒略历中一年中第一个月的 MONTH 字段值。
        //FEBRUARY--->指示在格里高利历和罗马儒略历中一年中第二个月的 MONTH 字段值。
        //MARCH--->指示在格里高利历和罗马儒略历中一年中第三个月的 MONTH 字段值。
        //APRIL--->指示在格里高利历和罗马儒略历中一年中第四个月的 MONTH 字段值。
        //MAY--->指示在格里高利历和罗马儒略历中一年中第五个月的 MONTH 字段值。
        //JUNE--->指示在格里高利历和罗马儒略历中一年中第六个月的 MONTH 字段值。
        //JULY--->指示在格里高利历和罗马儒略历中一年中第七个月的 MONTH 字段值。
        //AUGUST--->指示在格里高利历和罗马儒略历中一年中第八个月的 MONTH 字段值。
        //SEPTEMBER--->指示在格里高利历和罗马儒略历中一年中第九个月的 MONTH 字段值。
        //OCTOBER--->指示在格里高利历和罗马儒略历中一年中第十个月的 MONTH 字段值。
        //NOVEMBER--->指示在格里高利历和罗马儒略历中一年中第十一个月的 MONTH 字段值。
        //DECEMBER--->指示在格里高利历和罗马儒略历中一年中第十二个月的 MONTH 字段值。
        //AM--->指示从午夜到中午之前这段时间的 AM_PM 字段值。
        //PM--->指示从中午到午夜之前这段时间的 AM_PM 字段值。
        //如果在选定的字段组合中,还有尚未设置值的任一日历字段,那么 Calendar将使用其默认值。
        //每个字段的默认值可能依据具体的日历系统而有所不同。
        //例如,在 GregorianCalendar中,字段的默认值与历元起始部分的字段值相同:
        //即 YEAR = 1970、MONTH = JANUARY、DAY_OF_MONTH =1,等等。
        //Calendar 定义了某些日历字段返回值的范围,下面是GregorianCalendar中,各字段的最小与最大值:
        System.out.println(calendar1.getActualMinimum(Calendar.YEAR));//1
        System.out.println(calendar1.getActualMinimum(Calendar.MONTH));//0
        System.out.println(calendar1.getActualMinimum(Calendar.DATE));//1
        System.out.println(calendar1.getActualMinimum(Calendar.DAY_OF_YEAR));//1
        System.out.println(calendar1.getActualMinimum(Calendar.DAY_OF_MONTH));//1
        System.out.println(calendar1.getActualMinimum(Calendar.DAY_OF_WEEK));//1
        System.out.println(calendar1.getActualMinimum(Calendar.HOUR));//0
        System.out.println(calendar1.getActualMinimum(Calendar.HOUR_OF_DAY));//0
        System.out.println(calendar1.getActualMinimum(Calendar.MINUTE));//0
        System.out.println(calendar1.getActualMinimum(Calendar.SECOND));//0
        System.out.println(calendar1.getActualMinimum(Calendar.MILLISECOND));//0
        System.out.println(calendar1.getActualMaximum(Calendar.YEAR));//292278993
        System.out.println(calendar1.getActualMaximum(Calendar.MONTH));//11
        System.out.println(calendar1.getActualMaximum(Calendar.DATE));//31
        System.out.println(calendar1.getActualMaximum(Calendar.DAY_OF_YEAR));//365
        System.out.println(calendar1.getActualMaximum(Calendar.DAY_OF_MONTH));//31
        System.out.println(calendar1.getActualMaximum(Calendar.DAY_OF_WEEK));//7
        System.out.println(calendar1.getActualMaximum(Calendar.HOUR));//11
        System.out.println(calendar1.getActualMaximum(Calendar.HOUR_OF_DAY));//23
        System.out.println(calendar1.getActualMaximum(Calendar.MINUTE));//59
        System.out.println(calendar1.getActualMaximum(Calendar.SECOND));//59
        System.out.println(calendar1.getActualMaximum(Calendar.MILLISECOND));//999



        // Calendar时间日期的设置(set)
        // void set(int field, int value):
        // 将给定的日历字段设置为给定值。
        // void set(int year, int month, int date):
        // 设置日历字段 YEAR、MONTH 和 DAY_OF_MONTH 的值。
        // void set(int year, int month, int date, int hourOfDay, int minute):
        // 设置日历字段 YEAR、MONTH、DAY_OF_MONTH、HOUR_OF_DAY 和 MINUTE 的值。
        // void set(int year, int month, int date, int hourOfDay, int minute,int second):
        // 设置字段 YEAR、MONTH、DAY_OF_MONTH、HOUR、MINUTE 和 SECOND 的值。
        // void setTimeInMillis(long millis):
        // 用给定的 long 值设置此 Calendar 的当前时间值。
        calendar2.set(Calendar.YEAR, 2015);
        calendar2.set(Calendar.MONTH, 9);//十月份
        calendar2.set(Calendar.MONTH, Calendar.OCTOBER);//十月份
        calendar2.set(Calendar.DATE, 16);//2015-10-16
        calendar2.set(Calendar.DAY_OF_YEAR, 100);//2015年的第一百天--->2015-04-10
        calendar2.set(Calendar.DAY_OF_MONTH, 16);//2015-10-16 注意:这里的月份不是四月而是十月
        calendar2.set(Calendar.DAY_OF_WEEK, 1);//2015-10-11,1代表SUNDAY,而2015-10-11这一天就是SUNDAY
        calendar2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);//2015-10-12
        calendar2.set(Calendar.AM_PM,Calendar.PM);//下午
        calendar2.set(Calendar.HOUR, 0);//2015-10-12 12:51:14
        calendar2.set(Calendar.HOUR_OF_DAY, 20);//2015-10-12 20:51:46
        calendar2.set(Calendar.MINUTE, 4);//2015-10-12 20:04:27
        calendar2.set(Calendar.SECOND, 5);//2015-10-12 20:04:05
        calendar2.set(Calendar.MILLISECOND, 6);//2015-10-12 12:04:05.006
        calendar2.set(2015,9,12);//2015-10-12 设置Calendar对象的年、月、日三个字段的值
        calendar2.set(2015,9,12,14,1,23);//2015-10-12 14:01:23 设置Calendar对象的年、月、日、时、分、秒六个字段的值
        calendar2.setTimeInMillis(System.currentTimeMillis());//2015-10-16 14:07:56
        //set方法的注意事项:
        // set(f, value) 将日历字段 f 更改为 value。此外,它设置了一个内部成员变量,以指示日历字段 f已经被更改。
        // 尽管日历字段 f 是立即更改的,但是直到下次调用get()、getTime()、getTimeInMillis()、add() 或 roll()
        // 时才会重新计算日历的时间值(以毫秒为单位),即set()方法的延迟修改。因此,多次调用 set() 不会触发多次不必要的计算。
        // 使用 set()更改日历字段的结果是,其他日历字段也可能发生更改,这取决于日历字段、日历字段值和日历系统。
        // 示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。
        // 调用 set(Calendar.MONTH,Calendar.SEPTEMBER)将该日期设置为 1999年 9月 31日。
        // 如果随后调用 getTime(),那么这是解析1999 年 10 月 1 日的一个暂时内部表示。
        // 但是,在调用 getTime()之前调用set(Calendar.DAY_OF_MONTH, 30)会将该日期设置为 1999年 9月 30日,
        // 因为在调用 set()之后没有发生重新计算。



        // Calendar时间日期的获取(get)
        // int get(int field)
        // 返回给定日历字段的值。
        // long getTimeInMillis()
        // 返回此 Calendar 的时间值,以毫秒为单位。
        System.out.println(calendar1.get(Calendar.YEAR));//2015
        System.out.println(calendar1.get(Calendar.MONTH));//虽然是十月份,但显示的是9
        System.out.println(calendar1.get(Calendar.DATE));//16
        System.out.println(calendar1.get(Calendar.DAY_OF_YEAR));//289
        System.out.println(calendar1.get(Calendar.DAY_OF_MONTH));//16
        System.out.println(calendar1.get(Calendar.DAY_OF_WEEK));//6
        System.out.println(calendar1.get(Calendar.HOUR));//2
        System.out.println(calendar1.get(Calendar.HOUR_OF_DAY));//14
        System.out.println(calendar1.get(Calendar.MINUTE));//25
        System.out.println(calendar1.get(Calendar.SECOND));//52
        System.out.println(calendar1.get(Calendar.MILLISECOND));//537
        System.out.println(calendar1.getTimeInMillis());//1444976752537



        // Calendar对象的add()方法--->public abstract void add(int field,int amount):
        // 根据日历的规则,为给定的日历字段添加或减去指定的时间量。
        // 例如,要从当前日历时间减去 5天,可以通过调用以下方法做到这一点:
        // add(Calendar.DAY_OF_MONTH, -5)。
        // 相关注意事项:
        // add(f, delta) 将 delta 添加到 f 字段中。这等同于调用 set(f, get(f) +delta),但要带以下两个调整:
        //
        // 规则 (1).调用后 f 字段的值减去调用前 f 字段的值等于 delta,以字段 f中发生的任何溢出为模。
        // 溢出发生在字段值超出其范围时,结果,下一个更大的字段会递增或递减,并将字段值调整回其范围内。
        //
        // 规则 (2).如果期望某一个更小的字段是不变的,但让它等于以前的值是不可能的,因为在字段 f发生更改之后,或者在出现其他约束之后,
        // 比如时区偏移量发生更改,它的最大值和最小值也在发生更改,然后它的值被调整为尽量接近于所期望的值。
        // 对于不期望是不变字段的更小字段,无需进行任何调整。日历系统会确定期望不变的那些字段。
        //
        // 此外,与 set() 不同,add() 强迫日历系统立即重新计算日历的毫秒数和所有字段。
        // 示例:假定 GregorianCalendar 最初被设置为 1999 年 8 月 31 日。
        // 调用 add(Calendar.MONTH,13)将日历设置为 2000 年 9 月 30 日。
        // 规则 (1)将 MONTH 字段设置为 September,因为向August添加13个月得出的就是下一年的 September。
        // 因为在 GregorianCalendar中,DAY_OF_MONTH 不可能是 9 月 31 日,
        // 所以 规则 (2)将 DAY_OF_MONTH 设置为30,即最可能的值。



        // Calendar对象的roll()方法--->public abstract void roll(int field,boolean up)
        // 在给定的时间字段上添加或减去(上/下)单个时间单元,不更改更大的字段。
        // 例如,要将当前日期向上滚动一天,可以通过调用以下方法做到这一点:
        // roll(Calendar.DATE, true)。
        // 相关注意事项:
        // (1).在 year 或 Calendar.YEAR 字段上滚动时,
        // 将在从 1 到调用getMaximum(Calendar.YEAR) 的返回值之间的范围内滚动 year 值。
        // (2).在 month 或Calendar.MONTH 字段上滚动时,
        // 其他字段(如 date)可能发生冲突,因此需要更改它们。例如,在日期 1996-01-31 上滚动month 将产生 1996-02-29 的日期。
        // (3).在 hour-in-day 或 Calendar.HOUR_OF_DAY字段上滚动时,
        // 小时值会在 0 到 23 之间的范围内滚动,它是基于 0 的。



        // Calendar对象的roll()方法--->public void roll(int field,int amount)
        // 向指定日历字段添加指定(有符号的)时间量,不更改更大的字段。负的时间量意味着向下滚动。
        // 注:Calendar 上的此默认实现只是重复地调用滚动一个单元的 roll() 版本。




        //宽松性(容错性)
        //Calendar 有两种解释日历字段的模式,即 lenient 和 non-lenient。
        //当 Calendar 处于 lenient 模式时,它可接受比它所生成的日历字段范围更大范围内的值。
        //当 Calendar 重新计算日历字段值,以便由 get()返回这些值时,所有日历字段都被标准化。
        //例如,lenient模式下的 GregorianCalendar将 MONTH==JANUARY、DAY_OF_MONTH==32解释为 February 1。 
        //当 Calendar 处于 non-lenient 模式时,如果其日历字段中存在任何不一致性,它都会抛出一个异常。
        //例如,GregorianCalendar总是在 1与月份的长度之间生成 DAY_OF_MONTH值。
        //如果已经设置了任何超出范围的字段值,那么在计算时间或日历字段值时,处于 non-lenient 模式下的 GregorianCalendar 会抛出一个异常。 
        calendar1.setLenient(false);//默认是true
        System.out.println(calendar1.isLenient()==true?"true":"fasle");



        // equals和compareTo方法
        // public boolean equals(Object obj)将此 Calendar 与指定 Object比较。
        // 当且仅当参数是同一日历系统的 Calendar 对象时,结果才为 true,该日历系统将同一 Calendar
        // 参数下的同一时间值(从历元至现在的毫秒偏移量)表示为此对象。
        // Calendar 参数是通过 isLenient、getFirstDayOfWeek、getMinimalDaysInFirstWeek 和 getTimeZone 方法表示的值。
        // 如果在两个 Calendar 之间这些参数中存在任何不同之处,则此方法返回 false。 
        // 使用 compareTo 方法来仅对时间值进行比较。


    }

}

你可能感兴趣的:(java,源码,Class,日历)