当前位置: 首页 > 工具软件 > WebCalendar > 使用案例 >

Web基础之Calendar的应用

颛孙英才
2023-12-01

前言

在Web开发中也经常要做时间日期这样的操作,这篇文章简单的介绍了Calendar这个类的使用

正文

在java中经常使用到的两个操作时间的类是SimpleDateFormat和Calendar,前者主要是格式化指定的时间格式,后者则提供了非常丰富的时间操作的api,满足日常的业务需求
这里主要介绍一下Calendar这个类,可以先参考一下jdk7中的Calendar

Calendar两种模式

  1. lenient 模式:可以接收更大范围的Calenar字段,使用get方法它将重新计算这个字段,让所有的Calenar回到正常范围内。比如设置Calendar字段为1月32号,使用Calendar的get方法会得到2月1号
  2. non-lenient模式:这个模式和上面一个模式恰好相反,对任何的Calendar字段设置超过它对应的范围的值,则抛出异常。比如DAY_OF_MONTH 的范围在1-max,一旦超过这个范围就抛出一个异常

Calendar基本一些概念

DAY_OF_MONTH

当前时间在这个月是第几天,比如今天是11月10号,那么返回的就是10的值

WEEK_OF_MONTH

日历式的第几周,比如今天是2016年10月31,那么是10月1号是星期六,根据getFirstDayOfWeek知道一周的开始是星期日,那么10月1号(星期六-10月2号(星期日)为一周,10月2(星期日)号到8号(星期六)为第二周10月30号(星期日)-10月31号(星期一)是第六周
搭配calendar的get方法,返回的值就是当前时间在这个月的第几周

DAY_OF_WEEK_IN_MONTH

某月中第几周 按这个月1号算,1号起就是第1周,8号起就是第2周。以月份天数为标准

获取字段的最大值,最小值

getActualMaximum(int field)与getActualMinimum(int field),比如要获取本月最大周数,同理获取本月最大天数

    /**
      * 当前这个月最大的周数
      * @return
      */
     public static int weeksInMonth() {
         return calendar.getActualMaximum(Calendar.WEEK_OF_MONTH);
     }

获取/设置一周的开始时间

美的一周开始是周日,在法国是一周开始时间是周一,可以通过
下面两个方法获取和设置一周开始的时间。上面罗列的获取本月最大周数是和这个一周的开始时间相关的

     /**
      * 一周的第一天是星期几
      * 美国是星期日,而法国是星期一
      * 这里返回值为1(Month),所以默认星期日作为一周的开始
      * @return
      */
     public static int getFirstDayOfWeek() {
         return calendar.getFirstDayOfWeek();
     }
     /**
      * 设置星期几作为一个星期的第一天
      * Sunday = 1  saturday = 7
      * @param firstDay
      */
     public static void setFirstDayOfWeek(int firstDay) {
         calendar.setFirstDayOfWeek(firstDay);
     }

几个需要注意的api方法

  1. set方法
    /**
     * set(f, value),当使用set更改指定字段的值时,
     * 这个方法里面一个内部的成员变量记录了这个字段的变化,
     * 但是Calendar的时间值却未发送变化,除非调用以下方法
     * get(), getTime(), getTimeInMillis(), add(), or roll()
     * 当超过其内的字段的范围,就会自动调节,更大的字段增加或减少(模式1)
     */
    public static Date setMonth(int month) {
        //因为月份中0 代表一月,依次计算,这里为了符合正常逻辑思维,这里减去1调整
        calendar.set(Calendar.MONTH, month-1);
        return calendar.getTime();
    }
  1. add方法
    /**
     * add(f,delta)
     * rule1:在现在的f字段上,增加delta的值,如果当前的f字段超出范围,那么下一个最大的字段增加或者减少
     * 来调整这个f回到正常范围
     * rule2:当字段f增加了delta以后,比f小的字段期望是不变的,但是这是不能和原先相等,因为字段f的最小和最大范围在变
     * 或者其它约束如时区等,所以会调整为尽可能的接近之前的那个值,比如1992-8-31 ,add(Calendar.MONTH, 13),
     * 增加13个月后为2000-9-30. 比这个MONTH更小的字段 DAY_OF_MONTH不存在31,所以调整为最接近的数为30
     */
     public static Date addMonth(int month) {
         calendar.add(Calendar.MONTH, month);
         return calendar.getTime();
     }
  1. roll方法
    /**
     * roll(f,delta) 方法,比指定的field更大的field不会变
     * 比如指定是Month,那么比这个Month更大的字段就是YEAR
     * 当f增加delta后超出这个字段的范围(比如Month范围在1-12),那么比
     * 这个字段更大的字段(YEAR)是不会变的,而当前这个f字段的值是取范围的模
     */
    public static Date rollMonth(int month) {
        calendar.roll(Calendar.MONTH, month);
        return calendar.getTime();
    }

实战

情景:在学习Calendar的时候无意中看到了win10操作系统的时间样式,从上到下是时间,日期,日历的信息内容,故以此作为练习的例子
业务:

  1. 显示时间信息,按照“年月日,星期,时间“
  2. 可以随时更改哪一天作为一周的开始时间(周日,周一)
  3. 展现当前月份的所有周数的全部日期

代码:
根据哪天作为一周第一天来显示一周的星期文本,如:日 一 二 三 四 五 六

    /**
     * 使用循环与取模的方式,将固定数组中的值按照指定的方式展示
     * 更改firstDayOfWeek:DateUtil.setFirstDayOfWeek(Calendar.SUNDAY);
     * @return
     */
private String[] datas = new String[] {"日","一","二","三","四","五","六"};

public String getFirstDayOfWeekInfo() {
        StringBuffer info = new StringBuffer();
        int first = firstDayOfWeek = DateUtil.getFirstDayOfWeek(); //一周的第一天是星期几(日为1,六为7)
        //1-7取模
        int model = (first-1)%7;
        int pos = -1;
        while(pos != model) {
            info.append(datas[((first-1)%7)]).append("  ");
            first++;
            pos = (first-1)%7;
        }
        return info.toString();
    }

显示这个月的所有日期

    /**
     * 注意的是DateUtil这个工具类是共用一个Calendar对象
     * 里面的值一个更改是会影响到其他地方,请小心操作
     * @return
     */
    public void showCalendarInfo() {
        int begin = getBeginDateOfFirstWeek(); //第一周开始计算的日期
        int weeks = DateUtil.weeksInMonth(); //当月最大周数
        StringBuffer info = new StringBuffer();
        DateUtil.addDay(begin); //设置开始的时间起点,比如11月份第一周第一天是10月30号
        int increase = 1;
        while((weeks--)>0) { //一共有几周
            int count = 1;
            info.delete(0,info.length()); //清空
            while(count++ < 8) { //输出一周的日期
                String showDay = DateUtil.transform2Text(DateUtil.showCurrentDate(), "dd");
                info.append(showDay).append("   ");
                DateUtil.addDay(increase);//递增时间
            }
            System.out.println(info.toString());//换行
        }
    }
    private int getBeginDateOfFirstWeek() {
        DateUtil.setDay(1);//设置为当月的1号
        int firstDayOfWeekOfMonth = DateUtil.getDayOfWeek();
        //计算第一周的第一天的日期,比如2016-11月份的第一周的第一天是10月30号
        if(firstDayOfWeek > firstDayOfWeekOfMonth) {
            firstDayOfWeekOfMonth = firstDayOfWeekOfMonth+7;
        }
        //和当月1号相差的天数,回退到那一天
        int backDay = firstDayOfWeekOfMonth - firstDayOfWeek;
        return -backDay;
    }
 类似资料: