在Web开发中也经常要做时间日期这样的操作,这篇文章简单的介绍了Calendar这个类的使用
在java中经常使用到的两个操作时间的类是SimpleDateFormat和Calendar,前者主要是格式化指定的时间格式,后者则提供了非常丰富的时间操作的api,满足日常的业务需求
这里主要介绍一下Calendar这个类,可以先参考一下jdk7中的Calendar
当前时间在这个月是第几天,比如今天是11月10号,那么返回的就是10的值
日历式的第几周,比如今天是2016年10月31,那么是10月1号是星期六,根据getFirstDayOfWeek知道一周的开始是星期日,那么10月1号(星期六-10月2号(星期日)为一周,10月2(星期日)号到8号(星期六)为第二周10月30号(星期日)-10月31号(星期一)是第六周
搭配calendar的get方法,返回的值就是当前时间在这个月的第几周
某月中第几周 按这个月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);
}
/**
* 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();
}
/**
* 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();
}
/**
* 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操作系统的时间样式,从上到下是时间,日期,日历的信息内容,故以此作为练习的例子
业务:
代码:
根据哪天作为一周第一天来显示一周的星期文本,如:日 一 二 三 四 五 六
/**
* 使用循环与取模的方式,将固定数组中的值按照指定的方式展示
* 更改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;
}