Calendar中的Calendar.WEEK_OF_YEAR陷阱

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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值