JavaSE之Calendar类的练习

87 阅读5分钟

讲师强调的项目练习只做了一个,做完脑子还是不会,不是代码看不懂,而是不会对项目进行完整且专业的分析。这次的练习准备逐字逐句的进行记录,捋一下讲师的思路,看能不能复用。 上面这张图左边是原型图,右边是要写的代码。先观察原型图,录入的是xxxx-x-x的格式,然后再实现下边的逻辑功能,首先肯定是需要个强大的类,Calendar类不过时且强大。回到代码部分,首先要做的是将输入的字符串转成Calendar类,日历页面也用Calendar来做。

  1. 录入键盘输入的字符串代码:
package com.msb02;

import java.util.Scanner;

public class Test06 {
    public static void main(String[] args) {
        //String trans-to Calendar
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入你想要查看的日期(格式参考 2015-5-6):");
        String StrDate = sc.next();
        System.out.println(StrDate);
    }
}

/*终端结果:
请输入你想要查看的日期(格式参考 2015-5-6):1949-10-1
1949-10-1

Process finished with exit code 0
*/
/*说明能正常的接到从键盘传入的数据*/
  1. String转成Date类型:
//接着上面的代码
java.sql.Date date = java.sql.Date.valueOf(StrDate);
//这里就是将接收到的StrDate转成sql.Date
  1. Date 转成 Calendar类型:
//接着上面的代码
//首先当然要有个Calendar,直接创建对象报错,使用方式2后创建对象成功
Calendar cal = Calendar.getInstance();
cal.setTime(date);//将之前转成sql.Date的东西设置进去

到此时第一大步骤完成,第二大步骤“星期提醒”就需要构建从构建页面开始:

  1. 输出原型图第一行的内容:
System.out.println("日\t\t\t\t\t\t\t");
/*终端结果:
请输入你想要查看的日期(格式参考 2015-5-6):2015-5-6
2015-5-6
日        一        二        三        四        五        六        
*/
/*现在处于测试阶段,前面需要反复输入的东西可以给注释掉,在valueOf()参数写死"2019-5-18"
方便测试*/

2.确定当前月有几天:

/*也就是获取本月的最大天数*/
int maxDay = cal.getMaximum(Calendar.DATE);
System.out.println(maxDay);
/*因为是写死的时间数据,19年5月天数为31*/
/*终端结果:31*/

3.遍历当前月份的1-31天:

/*每在控制台输出一个数字,计数器做 +1 操作,Line 6 是每当计数器的个数是7的倍数时
就换行操作*/
int count = 0;
for(int i = 1; i <= maxDay;i++){
    System.out.print(i+"\t");
    count++;
    if ( count % 7 == 0 ){
        System.out.println();
    }
}

4.目标日期使用 * 来提醒

需要获取当前日int nowDay = cal.get(Calendar.DATE);接下来,每次当前日与变量i相同时就输出带上个。

//接着上面一部分的代码:
        int maxDay = cal.getMaximum(Calendar.DATE);
        int nowDay = cal.get(Calendar.DATE);
        //遍历:从1号到 maxDate 进行遍历
        int count = 0;
        for(int i = 1; i <= maxDay;i++){
            if (i == nowDay){
                System.out.print(i + "*"+"\t");
            }else{
                System.out.print(i+"\t");
            }
            count++;
            if ( count % 7 == 0 ){
                System.out.println();
            }
        }
    }
}

第三个步骤就是完善细节:

每月的1号肯定不都是星期日,这个时候需要日期与顶行的星期文本进行对应,核心难点就是在这里,如何对应?

在日期类里面提供了个方法cal.get(Calendar.DAY_OF_WEEK);,是用来说明当前日期在一个星期中的第几天,假设当前日期是一个月的第一天,知道是在一个星期的第几天就知道前面应该空几格,然后在对应的第一个日期前面打印空格。参考下图的实现代码:

//将日期调为本月的第一号:
cal.set(Calendar.DATE,1);
//获取这个1号是本周的第几天:
int num = cal.get(Calendar.DAY_OF_WEEK);
/*System.out.println(num);*/
//对应在页面里面,前面的空格数正好是num-1
int day = num - 1;
//在日期前将空格打印出来
for(int i = 1;i <= day;i++){
    System.out.print("\t");
}

这个时候代码,由于没有把空格也算进count计数器里面,导致了这样结果:

在打印空格语句后面添加:

//空出来的日子也要放入计时器:
count = count + day;

捋一下整体思路: 完整的源码:

package com.msb02;

import java.util.Calendar;
import java.util.Scanner;

public class Test06 {
    public static void main(String[] args) {
        //录入日期:
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入你想要查看的日期(格式参考 2015-5-6):");
        String StrDate = sc.next();
        System.out.println(StrDate);
        //String trans-to Calendar
        //1.String trans-to Date
        java.sql.Date date = java.sql.Date.valueOf(StrDate);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        System.out.println("日\t一\t二\t三\t四\t五\t六\t");
        int maxDay = cal.getActualMaximum(Calendar.DATE);
        int nowDay = cal.get(Calendar.DATE);

        //将日期调为本月的第一号:
        cal.set(Calendar.DATE,1);
        //获取这个1号是本周的第几天:
        int num = cal.get(Calendar.DAY_OF_WEEK);
        /*System.out.println(num);*/
        //对应在页面里面,前面的空格数正好是num-1
        int day = num - 1;
        //遍历:从1号到 maxDate 进行遍历
        int count = 0;
        //在日期前将空格打印出来
        for(int i = 1;i <= day;i++){
            System.out.print("\t");
        }
        //空出来的日子也要放入计时器:
        count = count + day;
        for(int i = 1; i <= maxDay;i++){
            if (i == nowDay){
                System.out.print(i + "*"+"\t");
            }else{
                System.out.print(i+"\t");
            }
            count++;
            if ( count % 7 == 0 ){
                System.out.println();
            }
        }
    }
}

关于日期的API从1.0的 Date 类到1.1的 Calendar 类,两代积累了需要解决的问题:1.之前学过的类里面有些对象通过set方法甚至可以更改时间,而现实需求中对于时间和日期这种类应该是不能改变的;2.有些类中的方法会涉及的偏移,比如应该是正常输出当前年份,而系统会与1900进行对比显示个百位数,以及月份显示的比实际的少1。3.格式化 : 格式化只对Date有用,Calendar则不行。 基于这上面三个明显的问题,后续JDK版本更新里第三批日期API......跟标题无关的内容就先不贴了。