Java基础进阶 工具类和时间日期类

1、工具类

Java中提供了大量的类和接口完成特定的功能。每个类都会有自己的属性和行为(功能)。但是这些功能还是不能满足所有的需求。于是Java中又对某些类提供的额外的功能。而把这些功能定义在特定的类中。
比如:集合类,每个集合类都提供可以操作自己这个集合容器中元素的函数。比如:添加元素、删除元素、修改元素、获取元素。而在开发中,对集合操作时,这些函数依然不够用。例:对有角标的集合进行排序、获取集合中最大值或者最小值等功能。于是Java又对这些集合类提供更多的功能,把这些功能定义在一个Collections类中。这个Collections类是一个专门给集合增加额外补充功能的类。

把这些专门提供补充或者额外增加功能的类在Java中称为工具类。
工具类的特点:
Java中所有的工具类中的函数全部都是静态的。并且工具类一般都会保存在java.util包下。

补充:如果自己在开发项目的时候,在整个项目中会专门建一个包来存放工具类的。
这个包我们一般这样命名:cn.xuexi.utils。

1.1、Collections工具类介绍

1.png

Collections工具类,主要就是操作集合的。如果当操作集合的时候,发现集合的方法不够用了,这时一定要先到Collections工具类中找有没有适合我们需求的功能。

Collections类中的常用方法:

1)

2.png

把可变参数指定的对象存放到指定的c集合中。

   public static <T> boolean addAll(Collection<?> c,T... elements)
3.png

2)对指定的集合进行排序。

 public static <T> void sort(List<T> list)
4.png

3)二分法查找或者叫做折半查找。

说明:使用二分法查找前提是一定要排序。否则查找的结果不是我们想要的。

 public static <T> <u>int</u> binarySearch(List<?> list,T key)

需求:找一下12在集合中的位置。

5.png

注意:根据指定的集合中的元素找对应的下标,如果指定的元素不在集合中。则返回(-(插入点) - 1),不是返回-1。按排序后插入数据。

6.png

4)求集合中元素的最大值。

  public static <T> T max(Collection<?> <u>coll</u>)
7.png

5)把指定的list集合中的元素进行反转。

public static void reverse(List<?> list)
8.png

6) 打乱集合中的数据顺序,这个函数经常使用在写扑克牌游戏中。

 public static void shuffle(List<?> list)
9.png

代码演示如下所示:

分析和步骤:
1)创建ArrayList<Integer>集合list,泛型是Integer;
2)使用集合对象list调用add函数向集合中添加几个整数类型的数据;
3)分别演示上述函数的功能;

package cn.xuexi.collections.demo;
import java.util.ArrayList;
import java.util.Collections;
/*
 * Collections的其他函数演示
 * public static <T> void sort(List<T> list) 对指定的集合进行排序
 * public static <T> int binarySearch(List<?> list,T key) 根据指定的集合中的元素查找对应的下标
 * public static <T> T max(Collection<?> coll) 求集合中元素的最大值
 * public static void reverse(List<?> list) 把指定的集合中的元素进行反转
 * public static void shuffle(List<?> list) 打乱集合中数据 
 */
public class CollectionsDemo1 {
    public static void main(String[] args) {
        // 创建集合对象
        ArrayList<Integer> list = new ArrayList<Integer>();
        //向集合中添加数据
        Collections.addAll(list, 12,34,2,18,57);
        //输出原始的集合
        System.out.println(list);
        //对集合进行排序
        Collections.sort(list);
        //输出排序后的集合
        System.out.println("排序后"+list);
        //需求:找一下12在集合中的位置 list表示集合名,12表示集合中的数据
        int index = Collections.binarySearch(list,12); 
        System.out.println(index);
        //求集合中元素的最大值
        Integer max = Collections.max(list);
        System.out.println("max="+max);
        //把指定集合中的元素进行反转
        Collections.reverse(list);
        System.out.println("反转后的集合"+list);
        //打乱集合中的数据
        Collections.shuffle(list);
        //输出打乱后的集合数据
        System.out.println("打乱后的集合"+list);
    }
}

1.2、Arrays工具类介绍

Arrays它是数组的工具类:

10.png

Arrays工具类中提供数组的:二分查找,复制数组,填充数组,排序,把数组转成字符串。但是没有提供对数组中的数据进行反转,求数组中的最值问题。
如果我们能够把数组转成集合,就可以使用Collections工具类中的最值和反转功能。
也就是说数组转换为集合的目的就是为了使用集合中的方法操作数组中的元素。

数组转集合的函数:

11.png
 public static <T> List<T> asList(T... a)

数组转成集合使用Arrays中的asList方法。
注意:将数组转成集合需要注意以下几点:
1)将数组转为一个集合,得到的集合长度固定。集合长度不能改变。
也就是说数组转换后的集合不能对集合增删元素,元素可以修改。
2)使用asList函数将数组转换为集合,由于asList函数的参数是可变参数,可以接收数组;
3)如果数组中存储的是引用数据类型的数据,比如字符串String类等,那么返回值List<T>的泛型是是String,而不是String[] 。

因为数组中保存的是引用数据类型的字符串对象,而集合是用来保存对象的,所以数组中的每个字符串对象数据都会放在集合中作为集合元素。

分析和步骤:
a.定义一个测试类ArraysDemo;
b.在这个类中的主函数中定义一个字符串数组,存储几个字符串,使用Arrays类调用asList()函数将数组转换为集合;
c.由于asList()函数是可变参数也可以接收可变参数,所以传递几个字符串作为可变参数在生成一个新的集合;
d.分别使用上述生成集合的对象演示对集合增删改操作,并输出结果;

package cn.xuexi.arrays.demo;
import java.util.Arrays;
import java.util.List;
/*
 * public static <T> List<T> asList(T... a) 
 * 使用上述函数将数组转换为集合,然后可以使用集合中的函数来操作数组
 * 注意:由于数组长度是固定的,转化为集合后,集合的长度也不能被改变
 */
public class ArraysDemo {
    public static void main(String[] args) {
        //创建数组
       //String[] arr={"hello","java","world"};
        /*
         * 使用asList函数将数组转换为集合
         * 由于asList函数的参数是可变参数,可以接收数组
         * 注意这里的泛型是String,不是String[] 
         * 因为数组中保存的是引用数据类型的字符串对象,而集合是用来保存对象的
         * 所以数组中的每个字符串对象数据都会放在集合中作为集合元素
         */
        //List<String> list = Arrays.asList(arr);
        //由于asList(T... a) 函数的参数是可变参数,所以可以向如下方式传递数据,
        //其实可变参数就是个数组  而参数的类型 T和集合的泛型一样都是String类型
        //T... a ={"hello","java","world"} T[] a={"hello","java","world"};
        //String[] a={"hello","java","world"};
        List<String> list = Arrays.asList("hello","java","world");
        //输出list [hello, java, world]
        //System.out.println(list);
        //向生成的集合中添加数据
        //list.add("哈哈");//不能向该集合中添加元素 否则报异常  java.lang.UnsupportedOperationException
        //list.remove(1);//不能删除该集合中的元素 否则报异常  java.lang.UnsupportedOperationException
        //可以修改集合中的数据,但是不能改变集合的长度
        list.set(0, "哈哈");
        System.out.println(list);
    }
}

4)如果数组中存储的是基本数据类型,那么数组转成集合,会把整个数组作为一个对象存储到集合中;

代码如下所示:

分析和步骤:
a.在上述类中的主函数中定义一个int[]数组,存储几个int类型的数据;
b.使用Arrays类调用asList()函数将数组转换为集合,并输出结果;


12.png

说明:输出集合名字能够输出一串地址,说明list集合中存储的是一个一维数组的一串地址,也就是说将数组整体作为集合的一个对象元素存储到集合中。

上述代码内存图解如下所示:

13.png

总结:如果想将数组转换为集合,让集合操作数组中的元素建议不要将基本数据类型数组转换为集合,可以将基本类型的数组变成对应的包装类类型数组在转换为集合即可。

5)如果数组中存储的是引用类型的元素,在把数组转为集合后,该集合中存储的就是数组中的所有引用类型的元素;

代码实现如下所示:
分析和步骤:
1)在上述类中的主函数中定义一个String[]数组,存储几个String类型的数据;
2)使用Arrays类调用asList()函数将String类型的数组转换为集合,并输出结果;
3)在上述类中的主函数中定义一个Integer[]数组,存储几个Integer类型的数据;
4)使用Arrays类调用asList()函数将Integer类型的数组转换为集合,并输出结果;

14.png

说明:Integer[]数组保存的是基本数据类型的包装类的对象的地址,属于引用数据类型,所以会将每一个数据保存到集合中。

上述代码的内存图解如下所示:

15.png

总结:
1)在开发中不建议将基本类型的数组通过asList()函数转换为集合,因为转换结果是地址,不是数组中的数据,可以将基本类型的数组换成对应的包装类类型数组进行转换;
2)把数组转成集合就是为了使用集合中的功能操作数组;

2、Date类介绍

在生活中有日期这样的数据,Java对日期这类数据也进行了类的描述和封装。

16.png

说明:
1)类 Date 表示特定的瞬间,精确到毫秒。
2)Date类,在JDK1.0的时候提供了大量的函数,可以进行年月日时分秒的转换,以及字符串和日期之间的转换和解析。后期从JDK1.1开始 ,年月日时分秒的转换交给了Calendar 类 ,而字符串和日期之间的转换交给了DateFormat类。

Date类中没有过时的构造函数如下:

17.png

创建一个Date对象,封装就是当前系统的时间信息。

18.png

把一个毫秒值封装成Date对象。

代码演示如下所示:
分析和步骤:
1)创建一个测试类DateDemo;
2)在这个类中的main函数中使用new关键字创建Date类的对象d;
3)输出当前的系统时间d;
4)根据日期对象d调用getTime()函数获得日期对象的毫秒值time,输出time值;
5)使用System调用currentTimeMillis()函数获得当前系统的毫秒值time2,输出毫秒值time2;
6)把毫秒值time2作为Date类的构造函数的参数生成日期类对象d2,并输出d2;

package cn.xuexi.date.demo;
import java.util.Date;
/*
 * Date类的演示
 */
public class DateDemo {
    public static void main(String[] args) {
        /*
         * 创建一个日期对象
         * 使用空参构造函数把当前的系统时间封装成Date类的对象
         */
        Date d = new Date();
        //输出当前系统时间d
        System.out.println(d);
        //根据日期对象d获得毫秒值
        long time = d.getTime();
        System.out.println(time);
        //使用System类中的函数获得当前系统的毫秒值
        long time2 = System.currentTimeMillis();
        System.out.println(time2);
        //根据毫秒值创建日期类的对象
        Date d2 = new Date(time2);
        System.out.println(d2);
    }
}

Date类没有过时的其他函数:


19.png

已经有一个Date对象,但是我们可以修改这个Date对象表示的毫秒值数据。

20.png

在Date类中必须知道怎么把毫秒值转成Date对象,以及怎么把Date对象转成毫秒值。

1.毫秒值转成Date对象:构造函数 Date(long time) 使用函数 setTime(long time);
2.Date对象转成毫秒值:使用函数getTime() System.currentTimeMillis()

3、DateFormat类介绍

21.png

说明:
1)在Java中看到文本,统一把这样的数据当做String处理;
2)DateFormat是一个抽象类,不能实例化。需要使用该类中的一个静态方法获取对象:

22.png

补充: 对于getDateInstance()函数而言,这里的日期默认风格是:年-月-日。yyyy-MM-dd

举例:2015-12-27

23.png

补充: 对于getDateTimeInstance()函数而言,这里的日期默认风格是:年-月-日 时:分:秒。 yyyy-MM-dd HH:mm:ss。

举例:2015-12-27 15:42:30

3)DateFormat类:可以把日期对象转成字符串数据(格式化),或者把字符串数据转成日期对象(解析);
A:日期转为字符串(格式化日期对象)

24.png

B:字符串转为日期(解析日期格式的字符串)

25.png

案例1:DateFormat简单使用
需求:把当前系统时间使用format(Date date)函数转换为字符串(格式化功能)。
分析和步骤:
1)使用DateFormat类调用getDateInstance()函数获得日期格式化解析的对象df;
2)创建当前系统的日期的对象d,new Date();
3)使用日期格式化解析的对象df调用format函数,把当前系统日期对象d转为字符串格式并输出;

package cn.xuexi.date.demo;
import java.text.DateFormat;
import java.util.Date;
/*
 * 需求:把当前系统时间使用format函数转换为字符串(格式化功能)。
 */
public class DateFormatDemo {
    public static void main(String[] args) {
        /*
         * 创建DateFormat类的对象
         * 由于DateFormat类是抽象类不能使用new关键字创建对象
         * 所以只能使用DateFormat类名调用函数来获得对象
         */
        //DateFormat df = DateFormat.getDateInstance();
        //System.out.println(df);//输出内容java.text.SimpleDateFormat@ef7951d7
        DateFormat df2 = DateFormat.getDateTimeInstance();
        //获得当前系统的时间
        Date d = new Date();
       //System.out.println(d);//输出结果Tue Dec 27 00:27:02 GMT+08:00 2015
        //使用DateFormat类的对象df调用format函数把当前系统时间转换为字符串
        /*String newDate = df.format(d);
        System.out.println(newDate);//输出内容:2015-12-27
        */  
        String newDate2 = df2.format(d);
        System.out.println(newDate2);//输出内容是2015-12-27 15:42:30
      }
}

案例2:把字符串对象转为日期对象(解析功能)

  • 需求:把当前系统时间使用format函数转换为字符串(格式化功能)。
    需求:将一个字符串对象"2016年10月19 日15时42分30秒”解析为日期格式的对象。
    说明:getDateTimeInstance()的日期格式是:yyyy-MM-dd HH:mm:ss。

分析和步骤:
1)使用DateFormat类调用getDateTimeInstance()函数获得日期格式化解析的对象df;
2)定义一个String类型的字符串strDate="2016年10月19 日15时42分30秒";
3)使用日期格式化解析的对象df调用parse()函数对上述字符串strDate进行解析;
4)输出解析后的数据;

26.png

结论:在进行解析时,必须保证字符串的日期格式和要解析的对象属于同一种格式
改进程序:

27.png

4、SimpleDateFormat类介绍(掌握)

28.png

说明:DateFormat类和子类SimpleDateFormat它们的主要功能就是完成日期和字符串之间的转换。

SimpleDateFormat类有一个比较重要的构造函数如下所示:

29.png

开发中经常使用上述构造函数创建SimpleDateFormat对象。因为上述构造函数在创建对象的时候,可以指定样式来对日期进行解析或格式化。

日期和时间的常见模式如下所示:

30.png

说明:
在使用SimpleDateFormat对日期数据进行格式化或者解析的时候,指定的模式:
yy表示简写的年份: 18年
yyyy表示全年: 2018年
M表示简写的月份: 6月
MM表示全月:06月
d 表示日:1
dd 表示日:01号
H小时: 8时
HH小时:08时
m分钟: 8分
mm分钟:08分
s秒:9秒
ss 秒:09秒

案例:使用SimpleDateFormat对象自定义风格解析和格式化日期对象。

需求:给定日期格式:yyyy年MM月dd日 HH时mm分ss秒。将当前系统时间按照给定的日期格式进行格式化,并输出结果。

代码如下所示:
分析和步骤:
1)定义一个测试类SimpleDateFormatDemo 类;
2)在这个类中的main函数中创建一个自定义的格式化解析器对象 要求参数格式:yyyy年MM月dd日 HH时mm分ss秒;
3)创建系统时间对象date,输出date;
4)将日期格式化为字符串newDate,并输出;

public class SimpleDateFormatDemo {
    public static void main(String[] args) {
        // 创建一个自定义的格式化解析器对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
        //创建系统日期对象
        Date date = new Date();
        //输出日期
        System.out.println(date);
        //将日期格式化为字符串
        String newDate = sdf.format(date);
        //输出格式化后的日期
        System.out.println(newDate);
      }
}

需求:将字符串"2018/06/01 13时17:20秒"按照指定日期格式"yyyy/MM/dd HH时mm:ss秒"解析成为系统日期时间。
分析和步骤:
1)定义一个测试类SimpleDateFormatDemo1 类;
2)在这个类中的main函数中创建一个自定义的格式化解析器对象sdf, 要求参数格式:yyyy/MM/dd HH时mm:ss秒;
3)定义一个字符串s用来保存日期:"2018/06/01 13时17:20秒";
4)使用日期格式化对象sdf调用parse()函数将字符串s解析成系统日期时间date,并输出转换后的日期date;

package cn.xuexi.date.demo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
 * 案例:使用SimpleDateFormat对象自定义风格解析和格式化日期对象
 */
public class SimpleDateFormatDemo {
    public static void main(String[] args) {
        //将字符串解析成为系统日期时间
        //定义一个字符串
        String strDate="2018/06/01 13时17:20秒";
        // 创建一个自定义的格式化解析器对象
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH时mm:ss秒");
        //使用sdf2调用parse()函数将上述字符串strDate解析成系统日期时间
        try {
            Date date2 = sdf2.parse(strDate);
            System.out.println(date2);
        } catch (Exception e) {
            System.out.println("日期格式不对,应该是:yyyy/MM/dd HH时mm:ss秒");
        }
    }
}

练习:"2014-08-09 09:09:09" 与 "2026年08/01 10:10:10" 相差多少个月。

分析和思路:
2个字符串形式表示的日期数据,要计算时间差,首先就需要获取到当前字符串表示的Date对象,然后通过Date对象在获取日期对象的毫秒值。
毫秒值是long型的数据,就可以使用算术运算计算差值。

分析和步骤:
1)创建一个SimpleDateFormatTest 测试类;
2)在这个类中的main函数中创建一个自定义的格式化解析器对象
sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
3)在创建一个自定义的格式化解析器对象
sdf2=new SimpleDateFormat("yyyy年MM/dd HH:mm:ss");
4)定义两个字符串s1和s2分别保存"2014-08-09 09:09:09"和"2026年08/01 10:10:10";
5)使用sdf和sdf2调用parse()函数将字符串解析成Date类的对象date1和date2;
6)使用date1和date2对象调用getTime()函数获取毫秒值t1和t2;
7)使用两个毫秒值t1和t2相互相减,然后进行算数运算,得到结果并输出即可;

package cn.xuexi.date.demo;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
 * 练习:"2014-08-09 09:09:09"  与  "2026年08/01 10:10:10"  相差多少月。
 */
public class SimpleDateFormatTest {
    public static void main(String[] args) {
        //创建格式化解析器对象
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM/dd HH:mm:ss");
        //定义两个字符串变量来保存日期
        String s1="2014-08-09 09:09:09";
        String s2="2026年08/01 10:10:10";
        //使用格式化解析器对象将上述字符串s1和s2解析成Date时间对象
        try {
            Date date1 = sdf.parse(s1);
            Date date2 = sdf2.parse(s2);
            //根据时间对象获得毫秒值
            long time1 = date1.getTime();
            long time2 = date2.getTime();
            /*
             * 两个时间相减 结果有可能为负数,所以我们可以让无论是正数还是负数都变成正数
             * Math.abs(time1-time2) 表示毫秒值相减的结果,而我们需要得知相差的月份
             * 所以得把毫秒值计算为月份
             */
            //long temp=Math.abs(time1-time2)/1000/60/60/24/365;//相差年份
               long temp=Math.abs(time1-time2)/1000/60/60/24/30;//相差月份
            System.out.println(temp);
        } catch (Exception e) {
            System.out.println("时间格式不对");
        }
    }
}

5、Calendar类介绍(掌握)

31.png

说明:
1)Calendar类是一个抽象类,不能实例化对象。(需要通过方法获取Calendar对象)


32.png

2)Calendar类属于一个日历类,记录了一些生活中常用的日历字段,比如年、月、日、时、分、秒等一些日期与时间的相关信息。

案例:Calendar类的使用。
分析和步骤:
1)创建一个CalendarDemo测试类;
2)在这个测试类的main函数中通过Calendar类调用getInstance()函数获得日历对象c;
3)输出日历对象c;

33.png

运行结果:

34.png

注意:
1)在计算机中月份是从零开始计算的。也就是说数字0 表示1月,数字1表示2月,以此类推数字11表示12月。12表示下一年的1月;
2)一周中周日是第一天;
3)Calendar类中输出结果是一些key-value对应的信息。其实在Calendar对象内部维护了一个Map集合,把当前系统日期与时间上的所有信息全部使用key=value的形式保存在Calendar这个类中。

问题:既然将当前系统日期与时间上的所有信息全部存在了一个Map集合中,那么当我们需要具体的什么信息时,是否可以直接通过这个Calendar类来获取,或者是否可以直接通过指定对应的key,拿到当前key对应的value值呢?
答案是可以的。

使用Calendar类中的get(int field)函数就可以获取Calendar对象中描述当前时间数据。需要根据指定的key来获取对应的value。

35.png

注意:Calendar类是用来保存某个时间点上的所有和时间相关的数据。然后我们就可以通过Calendar类中的静态成员变量作为key值(或者说作为get()函数的参数)来获取其中的任何一个value数据。

案例:获取Calendar对象中的日历字段。(想要输出” xxxx年xx月xx日”)
分析和步骤:
1)创建一个CalendarDemo1测试类;
2)在这个测试类的main函数中先创建Date类的对象d,通过对象d获得当前年、月、日,但是Date类中的函数都过期了;
3)通过Calendar类调用getInstance()函数获得日历对象c;
4)通过c对象调用get()函数,Calendar.YEAR、Calendar.MONTH、Calendar.DAY_OF_MONTH依次作为函数的参数来获得年、月(月份是从0开始的到11,所以获得月份需要+1)、日;
5)输出获得的年、月、日;

代码如下所示:

package cn.xuexi.date.demo;
import java.util.Calendar;
import java.util.Date;
/*
 * 案例:获取Calendar对象中的日历字段。(想要输出” xxxx年-xx月-xx日”)
 */
public class CalendarDemo1 {
    public static void main(String[] args) {
        // 创建时间日期类对象
        /*Date d = new Date();
        //获得系统的年月日
        int year = d.getYear();//年 当前系统时间减去1900
        int month = d.getMonth();//月 月份从0~11
        int day = d.getDate();//日 表示获得一个月中的某一天
        //int day1 = d.getDay();//日 表示获得一周中的某一天  0 表示星期日 1 表示星期一 2表示星期二
        //输出Date类获取的年月日
        System.out.println(year+"年"+month+"月"+day+"日");*/
        //Date日期类已经过期了,被Calendar日历类所取代了
        //创建日历类Calendar类的对象
        Calendar c = Calendar.getInstance();//使用静态方法获取日历对象
        //使用日历对象c调用get函数获得年份
        int year = c.get(Calendar.YEAR);//年
        int month = c.get(Calendar.MONTH)+1;//月份 从0开始到11
        int day = c.get(Calendar.DAY_OF_MONTH);//一个月中的某一天
        System.out.println(year+"年"+month+"月"+day+"日");
    }
}

3)Calendar类的set()和add()函数;

36.png

说明:给当前Calendar对象中的某个key设置value值。


37.png

说明:是在当前的时间点上添加某些时间。field 表示Calendar类中的成员变量,集合中key值。amount 表示当前指定的数据,这个数据可以是正数,也可以是负数。正数代表着在当前时间上加上amount 变量,负数代表着在当前时间上减去amount 变量。

案例:Calendar类的set方法和add方法
分析和步骤:
1)创建一个CalendarDemo2测试类;
2)在这个测试类的main函数中通过Calendar类调用getInstance()函数获得日历对象c;
3)使用对象c调用set()函数,并且Calendar.YEAR作为key,2011作为value来修改日历字段中的年份;
4)使用对象c调用set()函数来设置日历对象中的年月日;
5)使用对象c调用add()函数,Calendar.MONTH作为key,1作为value在当前日历对象的基础上增加一个月;
6)使用对象c调用add()函数,Calendar.DAY_OF_MONTH作为key,-1作为value在当前日历对象的基础上减少一天;
7)分别获得年月日,并输出获得的年、月、日;

package cn.xuexi.date.demo;
import java.util.Calendar;
/*
 * 案例:Calendar类的set方法和add方法
 */
public class CalendarDemo2 {
    public static void main(String[] args) {
        // 使用静态方法获得日历类对象
        Calendar c = Calendar.getInstance();
        //通过对象c调用set函数更改年
        //c.set(Calendar.YEAR, 2013);
        //更改日历对象中的年月日
        //c.set(2012, 1, 1);
        //System.out.println(c);
        /*
         * 这里的月份13超出了月份的范围11
         * 所以当月份或者天数超出了所属字段范围后,会修改前面的日历字段
         */
        //这里的月份13超出了月份的范围11 结果是2013年2月1日 月份超出了范围,修改年
        //c.set(2012, 13, 1);//2013年2月1日
        //这里的天数29超出了天数的范围28  结果是2017年3月1日 天数超出了范围,修改月
        c.set(2017, 1, 29);//2017年3月1日
        //使用日历对象c调用add函数修改日历中的数据
               //c.add(Calendar.MONTH, 1);//在当前月份上加1个月
        c.add(Calendar.DAY_OF_MONTH, -1);//在当前月的天数上减1
        //获取年月日
        int year=c.get(Calendar.YEAR);//年
        int month=c.get(Calendar.MONTH)+1;//月
        int day=c.get(Calendar.DAY_OF_MONTH);//日
        //输出
        System.out.println(year+"年"+month+"月"+day+"日");
    }
}

注意:
在使用set或add方法时,如果设置的日历字段超出当前字段所属范围后,就会修改前面日历字段的值:
1)月份超出了范围,修改年;
2)天数超出了范围,修改月;
3)如果日历字段设置的值为负数:就在当前日历字段的基础上减;
4)如果日历字段设置的值为正数:就在当前日历字段的基础上加;

面试题:
需求:使用最有效的方式获取指定年份中2月的最大天数。
分析:一年中的二月份的天数有29天(闰年)或者28天(平年),也就是说2月最大的天数要么是29,要么是28.
无论是29天还是28天,后一天肯定是3月1号,那么我们可以先获得一年中的3月1号,然后在1号的基础上减1,这样就获得了2月份的最大天数了。

分析和步骤:
1)创建CalendarTest类;
2)在CalendarTest类中使用Calendar调用getInstance()函数获得日历类的对象c;
3)使用日历类对象c调用set()函数把时间设置成某一年的3月1日;
4)使用日历类对象c调用add()函数把月中的天数-1;
5)日历类对象c调用get()函数获得年、月(月数+1)、日,并打印;

package cn.xuexi.date.demo;
import java.util.Calendar;
/*
 * 需求:使用最有效的方式获取指定年份中2月的最大天数。
 */
public class CalendarTest {
    public static void main(String[] args) {
        // 根据静态方法获取日历对象
        Calendar c = Calendar.getInstance();
        //使用日历对象c调用set函数把日期设置到某一年的3月1号
        for (int year = 1000; year < 2020; year++) {
             //设置某一年的3月1日
            c.set(year, 2, 1);//计算机中的月份0~11
            //三月份天数倒退一天,就是减少一天
            c.add(Calendar.DAY_OF_MONTH, -1);
            // 获取年月日
            int year2 = c.get(Calendar.YEAR);// 年
            int month = c.get(Calendar.MONTH) + 1;// 月
            int day = c.get(Calendar.DAY_OF_MONTH);// 日
            // 输出
            System.out.println(year2 + "年" + month + "月" + day + "日");
        }
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • 一、Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计...
    子非鱼_t_阅读 4,134评论 1 44
  • 一、基础知识:1、JVM、JRE和JDK的区别:JVM(Java Virtual Machine):java虚拟机...
    杀小贼阅读 2,357评论 0 4
  • 2017.10.16今天是恩施店长刘喜凤二阶毕业的日子,虽然没有亲临现场,但看着群里发来的视频,内心一阵阵小激动!...
    丽华1117阅读 170评论 3 1
  • 很多建站的朋友有时会忽略了网站的真正价值,完全没有考虑过网站的优化推广,从而让网站仅仅是一个摆设,因此建站后也需要...
    万能的小二阅读 1,306评论 0 0
  • 在百无聊赖的深夜,突然看到女儿上传的图片。“我在午后遇见你”湛蓝寥廓的天空,普通而疲惫的绝不美丽的蝴蝶...
    衣袂飘然阅读 148评论 0 0