我们国家有法定节假日,有因为法定节假日需要额外补班的周末,还有平常普通的周末,如何创建一个工具类,能很方便的知道这些信息呢?如下的代码能实现这些功能:

  • 给定日期,判断是否是法定节假日。
  • 给定日期,判断是否是周末(周末不一定是休息日,可能需要补班)。
  • 给定日期,判断是否是需要额外补班的周末。
  • 给定日期,判断是否是休息日(包含法定节假日和不需要补班的周末)。
  • 给定日期,判断是否是工作日(非休息日)。
  • 获取一年中总共的天数。
  • 获取一年中法定节假日的天数。
  • 获取一年中需要补班的周末天数。
  • 获取一年中周末的天数(周六+周日)。
  • 获取一年中休息日的天数(法定节假日+不需要补班的周末)。

代码:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 获取当年中国的法定节假日和工作日等信息。 如下是当前包含的功能:
 * 01-给定日期,判断是否是法定节假日。
 * 02-给定日期,判断是否是周末(周末不一定是休息日,可能需要补班)。 
 * 03-给定日期,判断是否是需要额外补班的周末。
 * 04-给定日期,判断是否是休息日(包含法定节假日和不需要补班的周末)。 
 * 05-给定日期,判断是否是工作日(非休息日)。
 * 06-获取一年中总共的天数。
 * 07-获取一年中法定节假日的天数。 
 * 08-获取一年中需要补班的周末天数。 
 * 09-获取一年中周末的天数(周六+周日)。
 * 10-获取一年中休息日的天数(法定节假日+不需要补班的周末)。
 * 
 */

public class ChineseCalendar {
    // 法律规定的放假日期
    private List<String> lawHolidays = new ArrayList<String>(Arrays.asList(
            "2017-01-01", "2017-01-02", "2017-01-27", "2017-01-28",
            "2017-01-29", "2017-01-30", "2017-01-31", "2017-02-01",
            "2017-02-02", "2017-04-02", "2017-04-03", "2017-04-04",
            "2017-04-29", "2017-04-30", "2017-05-01", "2017-05-28",
            "2017-05-29", "2017-05-30", "2017-10-01", "2017-10-02",
            "2017-10-03", "2017-10-04", "2017-10-05", "2017-10-06",
            "2017-10-07", "2017-10-08"));
    // 由于放假需要额外工作的周末
    private List<String> extraWorkdays = new ArrayList<String>(Arrays.asList(
            "2017-01-22", "2017-02-04", "2017-04-01", "2017-05-27",
            "2017-09-30"));

    /**
     * 判断是否是法定假日
     * 
     * @param calendar
     * @return
     * @throws Exception
     */
    public boolean isLawHoliday(String calendar) throws Exception {
        this.isMatchDateFormat(calendar);
        if (lawHolidays.contains(calendar)) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是周末
     * 
     * @param calendar
     * @return
     * @throws ParseException
     */
    public boolean isWeekends(String calendar) throws Exception {
        this.isMatchDateFormat(calendar);
        // 先将字符串类型的日期转换为Calendar类型
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(calendar);
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        if (ca.get(Calendar.DAY_OF_WEEK) == 1
                || ca.get(Calendar.DAY_OF_WEEK) == 7) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是需要额外补班的周末
     * 
     * @param calendar
     * @return
     * @throws Exception
     */
    public boolean isExtraWorkday(String calendar) throws Exception {
        this.isMatchDateFormat(calendar);
        if (extraWorkdays.contains(calendar)) {
            return true;
        }
        return false;
    }

    /**
     * 判断是否是休息日(包含法定节假日和不需要补班的周末)
     * 
     * @param calendar
     * @return
     * @throws Exception
     */
    public boolean isHoliday(String calendar) throws Exception {
        this.isMatchDateFormat(calendar);
        // 首先法定节假日必定是休息日
        if (this.isLawHoliday(calendar)) {
            return true;
        }
        // 排除法定节假日外的非周末必定是工作日
        if (!this.isWeekends(calendar)) {
            return false;
        }
        // 所有周末中只有非补班的才是休息日
        if (this.isExtraWorkday(calendar)) {
            return false;
        }
        return true;
    }

    /**
     * 判断是否是工作日
     * 
     * @param calendar
     * @return
     * @throws Exception
     */
    public boolean isWorkday(String calendar) throws Exception {
        this.isMatchDateFormat(calendar);
        return !(this.isHoliday(calendar));
    }

    public int getTotalDays() {
        return new GregorianCalendar().isLeapYear(Calendar.YEAR) ? 366 : 365;
    }

    public int getTotalLawHolidays() {
        return lawHolidays.size();
    }

    public int getTotalExtraWorkdays() {
        return extraWorkdays.size();
    }

    /**
     * 获取一年中所有周末的天数
     * @return
     */
    public int getTotalWeekends() {
        List<String> saturdays = new ArrayList<String>();
        List<String> sundays = new ArrayList<String>();
        Calendar calendar = Calendar.getInstance();
        int currentYear = calendar.get(Calendar.YEAR);
        int nextYear = 1 + calendar.get(Calendar.YEAR);
        Calendar cstart = Calendar.getInstance();
        Calendar cend = Calendar.getInstance();
        cstart.set(currentYear, 0, 1);// 今年的元旦
        cend.set(nextYear, 0, 1);// 明年的元旦
        return this.getTotalSaturdays(saturdays, calendar, cstart, cend,
                currentYear)
                + this.getTotalSundays(sundays, calendar, cstart, cend,
                        currentYear);
    }

    private int getTotalSaturdays(List<String> saturdays, Calendar calendar,
            Calendar cstart, Calendar cend, int currentYear) {
        // 将日期设置到上个周六
        calendar.add(Calendar.DAY_OF_MONTH, -calendar.get(Calendar.DAY_OF_WEEK));
        // 从上周六往这一年的元旦开始遍历,定位到去年最后一个周六
        while (calendar.get(Calendar.YEAR) == currentYear) {
            calendar.add(Calendar.DAY_OF_YEAR, -7);
        }
        // 将日期定位到今年第一个周六
        calendar.add(Calendar.DAY_OF_YEAR, 7);
        // 从本年第一个周六往下一年的元旦开始遍历
        for (; calendar.before(cend); calendar.add(Calendar.DAY_OF_YEAR, 7)) {
            saturdays.add(calendar.get(Calendar.YEAR) + "-"
                    + calendar.get(Calendar.MONTH) + "-"
                    + calendar.get(Calendar.DATE));
        }
        return saturdays.size();
    }

    private int getTotalSundays(List<String> sundays, Calendar calendar,
            Calendar cstart, Calendar cend, int currentYear) {
        // 将日期设置到上个周日
        calendar.add(Calendar.DAY_OF_MONTH,
                -calendar.get(Calendar.DAY_OF_WEEK) + 1);
        // 从上周日往这一年的元旦开始遍历,定位到去年最后一个周日
        while (calendar.get(Calendar.YEAR) == currentYear) {
            calendar.add(Calendar.DAY_OF_YEAR, -7);
        }
        // 将日期定位到今年第一个周日
        calendar.add(Calendar.DAY_OF_YEAR, 7);
        // 从本年第一个周日往下一年的元旦开始遍历
        for (; calendar.before(cend); calendar.add(Calendar.DAY_OF_YEAR, 7)) {
            sundays.add(calendar.get(Calendar.YEAR) + "-"
                    + calendar.get(Calendar.MONTH) + "-"
                    + calendar.get(Calendar.DATE));
        }
        return sundays.size();
    }

    public int getTotalHolidays(){
        //先获取不需要补班的周末天数
        int noWorkWeekends = this.getTotalWeekends() - this.getTotalExtraWorkdays();
        return noWorkWeekends + this.getTotalLawHolidays();
    }

    /**
     * 使用正则表达式匹配日期格式
     * 
     * @throws Exception
     */
    private void isMatchDateFormat(String calendar) throws Exception {
        Pattern pattern = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
        Matcher matcher = pattern.matcher(calendar);
        boolean flag = matcher.matches();
        if (!flag) {
            throw new Exception("输入日期格式不正确,应该为2017-02-03");
        }
    }

    public static void main(String[] args) throws Exception {
        String calendar = "2017-02-04";
        ChineseCalendar cc = new ChineseCalendar();
        System.out.println("是否是法定节假日:" + cc.isLawHoliday(calendar));
        System.out.println("是否是周末:" + cc.isWeekends(calendar));
        System.out.println("是否是需要额外补班的周末:" + cc.isExtraWorkday(calendar));
        System.out.println("是否是休息日:" + cc.isHoliday(calendar));
        System.out.println("是否是工作日:" + cc.isWorkday(calendar));
        System.out.println("今年总共有" + cc.getTotalDays() + "天");
        System.out.println("今年总共有" + cc.getTotalLawHolidays() + "天法定节假日");
        System.out.println("今年总共有" + cc.getTotalExtraWorkdays() + "天需要补班的周末");
        System.out.println("今年总共有" + cc.getTotalWeekends() + "天周末");
        System.out.println("今年总共有" + cc.getTotalHolidays() + "天休息日");
    }

}

运行结果如下:

是否是法定节假日:false
是否是周末:true
是否是需要额外补班的周末:true
是否是休息日:false
是否是工作日:true
今年总共有365天
今年总共有26天法定节假日
今年总共有5天需要补班的周末
今年总共有105天周末
今年总共有126天休息日

注意:
每年需要重新初始化法定节假日额外补班的周末