有时候需要根据工作日计算指定的日期,也就是需要排除周六日。

1.  初版代码如下:

package cn.xm.exam.utils;

import java.util.Calendar;
import java.util.Date; import org.apache.commons.lang.time.DateFormatUtils; public class WorkDayCalculateUtils {
public static void main(String[] args) {
Date date = getDate(new Date(), -7);
System.out.println(DateFormatUtils.format(date, "yyyy-MM-dd"));
} public static Date getDate(Date currentDate, int days) {
if (days == 0) {
return currentDate;
} Calendar calendar = Calendar.getInstance();
calendar.setTime(currentDate); int step = days < 0 ? -1 : 1;
int i = 0;
int daysAbs = Math.abs(days);
while (i < daysAbs) {
calendar.add(Calendar.DATE, step);
i++;
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
|| calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { i--;
}
} return calendar.getTime();
}
}

结果:

2019-08-14

日历如下:

2.  排除特殊工作日和休息日

  上面是按照所有的周一到周五休息、周六到周日工作来计算的,但是遇到国家法定节假日也需要进行特殊对待。

package cn.xm.exam.utils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List; import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils; public class WorkDayCalculateUtils { /**
* 特殊的工作日(星期六、日工作)
*/
private static final List<String> SPECIAL_WORK_DAYS = new ArrayList<>(); /**
* 特殊的休息日(星期一到五休息)
*/
private static final List<String> SPECIAL_REST_DAYS = new ArrayList<>(); static {
initSpecialDays();
} public static Date getDate(Date currentDate, int days) {
if (days == 0) {
return currentDate;
} Calendar calendar = Calendar.getInstance();
calendar.setTime(currentDate); int step = days < 0 ? -1 : 1;
int i = 0;
int daysAbs = Math.abs(days);
while (i < daysAbs) {
calendar.add(Calendar.DATE, step);
i++;
if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
|| calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) { // 周六日如果上班就算1个工作日
if (!SPECIAL_WORK_DAYS.contains(DateFormatUtils.format(calendar.getTime(), "yyyy-MM-dd"))) {
i--;
}
} else {
// 周1到周五休息就算1个休息日
if (SPECIAL_REST_DAYS.contains(DateFormatUtils.format(calendar.getTime(), "yyyy-MM-dd"))) {
i--;
}
}
} return calendar.getTime();
} /**
* 手工维护特殊日(因为是未知的,所以必须手工维护)
*/
private static void initSpecialDays() {
SPECIAL_WORK_DAYS.add("2019-09-29");
SPECIAL_WORK_DAYS.add("2019-10-12"); SPECIAL_REST_DAYS.add("2019-10-01");
SPECIAL_REST_DAYS.add("2019-10-02");
SPECIAL_REST_DAYS.add("2019-10-03");
SPECIAL_REST_DAYS.add("2019-10-04");
SPECIAL_REST_DAYS.add("2019-10-07");
} public static void main(String[] args) throws ParseException {
Date date = getDate(DateUtils.parseDate("2019-10-01", "yyyy-MM-dd"), 6);
System.out.println(DateFormatUtils.format(date, "yyyy-MM-dd"));
}
}

结果:

2019-10-14

日历:

  注意:上面的SPECIAL_WORK_DAYS、SPECIAL_REST_DAYS需要手工进行维护,这两个集合的数据来源可以的properties配置文件、xml文件或者数据库,建议采用properties配置文件进行配置,之后读取配置文件进行字符串切割。

Java计算工作日的工具类的更多相关文章

  1. Java日期时间实用工具类

    Java日期时间实用工具类 1.Date (java.util.Date)    Date();        以当前时间构造一个Date对象    Date(long);        构造函数   ...

  2. Redis 工具类 java 实现的redis 工具类

    最近了解了一下非关系型数据库 redis 会使用简单的命令 在自己本地电脑 使用时必须先启动服务器端 在启动客户端 redis 简介 Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内 ...

  3. 简化bigdecimal计算的小工具类

    简化bigdecimal计算的小工具类 如果我们要做一个加法运算,需要先将两个浮点数转为String,然后够造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果( ...

  4. 最全的Java操作Redis的工具类,使用StringRedisTemplate实现,封装了对Redis五种基本类型的各种操作!

    转载自:https://github.com/whvcse/RedisUtil 代码 ProtoStuffSerializerUtil.java import java.io.ByteArrayInp ...

  5. Java线程的并发工具类

    Java线程的并发工具类. 一.fork/join 1. Fork-Join原理 在必要的情况下,将一个大任务,拆分(fork)成若干个小任务,然后再将一个个小任务的结果进行汇总(join). 适用场 ...

  6. Rhino+envjs-1.2.js 在java运行网站js 工具类

    java爬虫遇到个页面加密的东西,找了些资料学习学习 做了个java运行js的工具类,希望对大家有用,其中用到client(获取js)可以自行换成自己的client.主要是用了 Rhino就是Java ...

  7. java中常用的工具类(一)

    我们java程序员在开发项目的是常常会用到一些工具类.今天我汇总了一下java中常用的工具方法.大家可以在项目中使用.可以收藏!加入IT江湖官方群:383126909 我们一起成长 一.String工 ...

  8. Java学习-041-颜色工具类(RGB,HEX)

    在日常的网页开发中,经常需要进行颜色数值获取.转换,例如获取红色,获取蓝色,获取绿色,RGB转十六进制颜色,十六进制颜色转RGB等,因而在学习过程中,写了一个小工具类,仅供各位小主参考! 多不闲言,直 ...

  9. JAVA中封装JSONUtils工具类及使用

    在JAVA中用json-lib-2.3-jdk15.jar包中提供了JSONObject和JSONArray基类,用于JSON的序列化和反序列化的操作.但是我们更习惯将其进一步封装,达到更好的重用. ...

随机推荐

  1. zookeeper知识点总结

    1. 关于ZooKeeper集群服务器数: ZooKeeper 官方确实给出了关于奇数的建议,但绝大部分 ZooKeeper 用户对于这个建议认识有偏差.一个 ZooKeeper 集群如果要对外提供可 ...

  2. JavaWeb 分层设计、MVC

    M:Model,JavaBean. V:View,JSP. C:Controller,Servlet. Servlet: 接受用户请求,把请求参数封装为一个JavaBean,调用service来处理业 ...

  3. using 中写 return 一样会释放using 中对象 但是会在外面定义一个一样的对象 赋值后 释放 最后 return 外面定义的那个对象

    static DataTable getDataTable() { ")) { SqlCommand com = new SqlCommand("", con); Sql ...

  4. Nginx基础知识介绍

    Nginx基础知识介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Nginx概述 Nginx是免费的.开源的.高性能的HTTP和正向/反向代理服务器.邮件代理服务器.以及T ...

  5. 八、collection系列-----计数器、有序字典、默认字典、可命名元组、双向队列、单向队列一.计数器(对字典的扩展)

    一.计数器(对字典的扩展) 有如下一个字典: dic = {'k1':123,'k2':123,'k3':12} 统计12出现的次数,123出现的次数   1.统计出现次数 >>> ...

  6. Manacher算法(马拉车)求最长回文子串

    Manacher算法求最长回文字串 算法思路 按照惯例((・◇・)?),这里只是对算法的一些大体思路做一个描述,因为找到了相当好理解的博客可以参考(算法细节见参考文章). 一般而言,我们的判断回文算法 ...

  7. tf.Variable()、tf.get_variable()和tf.placeholder()

    1.tf.Variable() tf.Variable(initializer,name) 功能:tf.Variable()创建变量时,name属性值允许重复,检查到相同名字的变量时,由自动别名机制创 ...

  8. opencv2配置window

    https://opencv.org/ opencv2 opencv3  opencv4 (现在到4版本) 二值化  图像拉伸 灰度  图像腐蚀 车牌识别 配置:https://blog.csdn.n ...

  9. 使用ARP获取局域网内设备IP和MAC地址

    根据Arp列表数据,查询本地设备在线状态 使用 arp -a 获得所有内网地址,首先看Mod对象 public struct MacIpPair { public string HostName; p ...

  10. cordova 一个将web应用程序封装成app的框架

    cordova的详细介绍请参考这个链接:http://www.zhoujingen.cn/blog/7034.html 我接下来主要将如何搭建. 1.首先你需要下载几样东西 1.jdk. 2.andr ...