1. 问题重现:当我们想使用Calendar.WEEK_OF_YEAR来求出2015-12-31属于2015年的第几周时,这里就会出现问题了。一年有52周,而2015-12-31这一天是2015年的第53周,其实是2016年的第一周,所有这使用Calendar中的Calendar.WEEK_OF_YEAR时,就要注意这个陷阱了。2015-12-31求出来的结果是1.
重现代码测试:我们将每周一作为一周的开始
package com.stephen.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class WeekOfYear {
public static void main(String[] args) {
String date1String = "2015-12-31 ";
String date2String = "2016-01-01 ";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
try {
Date date1 = sdf.parse(date1String);
Date date2 = sdf.parse(date2String);
Calendar calendar = Calendar.getInstance();
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar.setTime(date1);
int week1 = calendar.get(Calendar.WEEK_OF_YEAR);
System.out.println(date1String + " week of year:" + week1);
calendar.setTime(date2);
int week2 = calendar.get(Calendar.WEEK_OF_YEAR);
System.out.println(date2String + " week of year:" + week2);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
输出结果:
2015-12-31 week of year:1
2016-01-01 week of year:1
2. 出现原因: 它将2015年12月的28,29,30,31号都当成是2016年的第1周了
3. 解决方案, 我们这里是为了求出两个日期之间的周数,在同一周我们把周数记为1,一个在上一周,一个在当前周,我们把周数记为2,以此类推
package com.stephen.util;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateTimeUtil {
public static Integer getWeekOfYear(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar.setTime(date);
int week = calendar.get(Calendar.WEEK_OF_YEAR);
int mouth = calendar.get(Calendar.MONTH);
// JDK think 2015-12-31 as 2016 1th week
//如果月份是12月,且求出来的周数是第一周,说明该日期实质上是这一年的第53周,也是下一年的第一周
if (mouth >= 11 && week <= 1) {
week += 52;
}
return week;
}
public static Integer getYearOfDate(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.YEAR);
}
public static Integer weeksBetween(Date fromDate, Date toDate) {
if (fromDate.before(toDate)) {
Date temp = fromDate;
fromDate = toDate;
toDate = temp;
}
Integer weekNum = (getWeekOfYear(fromDate) - getWeekOfYear(toDate))
+ (getYearOfDate(fromDate) - getYearOfDate(toDate)) * 52;
return ++weekNum;
}
public static void main(String[] args) {
String formDateString = "2015-12-31 ";
String toDateString = "2016-01-01 ";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd ");
try {
Date formDate = sdf.parse(formDateString);
Date toDate = sdf.parse(toDateString);
System.out.println(weeksBetween(formDate, toDate));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
测试结果:1