银行等单位工作日计算的实现

原先想在JavaEye上发表这篇日志,可是论坛规则小测验让我倍感麻烦,所以暂且让它出现在QZone。

  下面就进入正题,这里主要介绍工作日实现的思路及实现。

  年末有段时间需要维护新疆FOA,其中有个需求就是在数据库中查询某个时间段工作日>3天的记录。由于同时存在农历和阳历,造成有些工作日可以休息或者有些周末要正常上班的问题,所以计算工作日还需要考虑到这个问题。

  先介绍下工作日计算的思路:

  1、确定计算公式

    工作日 = 正常工作日 - 工作休息日 + 休息工作日

     说明:正常工作日:按照阳历算出除去周六周日的天数。

        工作休息日:在正常工作日下的休息天数。如国庆、春节7天,工作日可以休息。

        休息工作日:在周末需要正常上班的天数。如国庆、春节后需要在周六或者周日正常上班。

  2、根据公式选择实现方式

    正常工作日实现:遍历某个时间段内每一天,过滤掉周六周日,最终得到正常工作日天数。

    工作休息日实现:将工作休息日的日期写入字典,提供对比,最终计算出工作休息日的天数。

    休息工作日实现:类似工作休息日实现方式。

    说明:由于实现方式简单,以文字方式可以描述清楚问题,这里就不考虑画流程图。

  下面简要介绍Java语言的实现:

  1、类图

    (QZone不支持日志图片上传,转到JavaEye下再上传图片)

  2、实现源代码(代码注释有不周到处请谅解)

/* ==================================================================

* Created [2010-1-22 下午05:00:29] by Neal Miao

* ==================================================================

* XXX

* ==================================================================

* XXX  License v1.0

* Copyright (c) Gsoft S&T Co.ltd HangZhou, 2009-2010

* ==================================================================

* 杭州中科天翔科技有限公司拥有该文件的使用、复制、修改和分发的许可权

* 如果你想得到更多信息,请访问 <http://www.g-soft.com.cn>

*

* Gsoft S&T Co.ltd HangZhou owns permission to use, copy, modify and

* distribute this documentation.

* For more information on gs, please

* see <http://www.g-soft.com.cn>.

* ==================================================================

*/

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.Date;

import java.util.LinkedList;

import java.util.List;

/**

* <p>

* WeekdayCounter.java

* </p>

* <p>

* 可用于工作日计算。<br>

* 由于中国的部分节假日为农历节日,如春节、清明节等等。

* 从而使得工作日和周末的混乱,计算工作日要重新考虑。

* </p>

*

* @author $Author: nealmiao $

* @version $Revision: 1.1 $

*/

public class WeekdayCountHelper {

/** 控制是否显示console */

private static boolean needConsoleInfo = false;

/**

* needConsoleInfo

*

* @return  the needConsoleInfo

* @since   Ver 1.0

*/

public static boolean isNeedConsoleInfo() {

return needConsoleInfo;

}

/**

* needConsoleInfo

*

* @param   needConsoleInfo    the needConsoleInfo to set

* @since   Ver 1.0

*/

public static void setNeedConsoleInfo(boolean needConsoleInfo) {

WeekdayCountHelper.needConsoleInfo = needConsoleInfo;

}

/**

* 判断工作日是否大于3,如果是则返回true

*

* @param revDate

* @param retnDate

* @return 返回判断工作日是否大于3结果。

* @since Ver 1.0

*/

public static boolean isValid(Date revDate, Date retnDate) {

if (getWeekDays(revDate, retnDate, null, null) > 3) {

return true;

} else {

return false;

}

}

/**

* 判断工作日是否大于3

*

* @param revDate

* @param retnDate

* @param specialHolidayList

* @param specialNonHolidayList

* @return 返回判断工作日是否大于3结果。

* @since Ver 1.0

*/

public static boolean isValid(Date revDate, Date retnDate,

List<Date> specialHolidayList, List<Date> specialNonHolidayList) {

if (getWeekDays(revDate, retnDate, specialHolidayList,

specialNonHolidayList) > 3) {

return true;

} else {

return false;

}

}

/**

* 判断工作日是否大于3

*

* @param startDate

* @param endDate

* @param specialHolidayList

* @param specialNonHolidayList

* @throws ParseException

* @return boolean

* @since Ver 1.0

*/

public static boolean isValid(String startDate, String endDate,

List<Date> specialHolidayList, List<Date> specialNonHolidayList)

throws ParseException {

if (isNeedConsoleInfo()) {

System.out.println("/nFrom " + startDate + " to " + endDate);

}

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

return isValid(format.parse(startDate), format.parse(endDate),

specialHolidayList, specialNonHolidayList);

}

/**

* 根据日期判断是否为周末,只考虑周六和周日。

*

* @param date

* @return 返回是否为周末。

* @since Ver 1.0

*/

public static boolean isWeekend(Date date) {

Calendar calendar = Calendar.getInstance();

calendar.setTime(date);

int week = calendar.get(Calendar.DAY_OF_WEEK);

if (Calendar.SUNDAY == week || Calendar.SATURDAY == week) {

return true;

} else {

return false;

}

}

/**

* 周末要上班的天数

*

* @param startDate

* @param endDate

* @param specialHolidayList

* @return int

* @exception

* @since Ver 1.0

*/

public static int getSpecialNonHolidays(Date startDate, Date endDate,

List<Date> specialNonHolidayList) {

Calendar start = Calendar.getInstance();

start.setTime(startDate);

Calendar end = Calendar.getInstance();

end.setTime(endDate);

Calendar compareDate = Calendar.getInstance();

int days = 0;

while (start.compareTo(end) <= 0) {

for (Date date : specialNonHolidayList) {

compareDate.setTime(date);

int day = compareDate.get(Calendar.DAY_OF_WEEK);

if (day == Calendar.SUNDAY || day == Calendar.SATURDAY) {

if (start.compareTo(compareDate) == 0) {

days++;

continue;

}

} else {

// do nothing, 过滤掉输入的周末日期

}

}

start.set(Calendar.DATE, start.get(Calendar.DATE) + 1);

}

if (isNeedConsoleInfo()) {

System.out.print("周末上班的工作日:" + days + "/t");

}

return days;

}

/**

* 特殊工作日,主要由农历节日引起。

*

* @param startDate

* @param endDate

* @param specialHolidayList

* @return int

* @exception

* @since Ver 1.0

*/

public static int getSpecialHolidays(Date startDate, Date endDate,

List<Date> specialHolidayList) {

Calendar start = Calendar.getInstance();

start.setTime(startDate);

Calendar end = Calendar.getInstance();

end.setTime(endDate);

Calendar compareDate = Calendar.getInstance();

int days = 0;

while (start.compareTo(end) <= 0) {

for (Date date : specialHolidayList) {

compareDate.setTime(date);

int day = compareDate.get(Calendar.DAY_OF_WEEK);

if (day == Calendar.SUNDAY || day == Calendar.SATURDAY) {

// do nothing, 过滤掉输入的非周末日期

} else {

if (start.compareTo(compareDate) == 0) {

days++;

continue;

}

}

}

start.set(Calendar.DATE, start.get(Calendar.DATE) + 1);

}

if (isNeedConsoleInfo()) {

System.out.print("正常工作日的休息日:" + days + "/t");

}

return days;

}

/**

* 循环遍历日期,获取工作日天数。

*

* @param startDate 起始日期

* @param endDate 结束日期

* @return 返回工作日天数。

* @since Ver 1.0

*/

public static int getNormalWeekdays(Date startDate, Date endDate) {

Calendar start = Calendar.getInstance();

start.setTime(startDate);

Calendar end = Calendar.getInstance();

end.setTime(endDate);

int days = 0;

while (start.compareTo(end) <= 0) {

int day = start.get(Calendar.DAY_OF_WEEK);

start.set(Calendar.DATE, start.get(Calendar.DATE) + 1);

if (day == Calendar.SUNDAY || day == Calendar.SATURDAY) {

continue;

} else {

days++;

}

}

if (isNeedConsoleInfo()) {

System.out.print("正常工作日:" + days + "/t");

}

return days;

}

/**

* 计算获得实际工作天数。<br>

* 工作天数 = 计算公式正常的工作天数-特殊的(农历)节假日+特殊的工作日

*

* @param startDate

* @param endDate

* @param specialHolidayList

* @param specialNonHolidayList

* @return 返回实际工作日天数。

*/

public static int getWeekDays(Date startDate, Date endDate,

List<Date> specialHolidayList, List<Date> specialNonHolidayList) {

int days = getNormalWeekdays(startDate, endDate)

- getSpecialHolidays(startDate, endDate, specialHolidayList)

+ getSpecialNonHolidays(startDate, endDate, specialNonHolidayList);

if (isNeedConsoleInfo()) {

System.out.print("/n实际工作日:" + days + "/t");

}

return days;

}

public static void main(String[] args) throws ParseException {

SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

List<Date> holidayList = new LinkedList<Date>();

holidayList.add(format.parse("2010-2-10"));

holidayList.add(format.parse("2010-2-9"));

holidayList.add(format.parse("1990-2-9"));

List<Date> nonHolidayList = new LinkedList<Date>();

nonHolidayList.add(format.parse("2010-2-13"));

setNeedConsoleInfo(true);

isValid("2010-2-8", "2010-2-13", holidayList,      nonHolidayList);

isValid("1992-2-8", "2010-2-13", holidayList,      nonHolidayList);

isValid("1990-2-8", "2010-2-13", holidayList,      nonHolidayList);

isValid("1990-2-8", "1990-2-13", holidayList,      nonHolidayList);

}

}

  测试结果:

From 2010-2-8 to 2010-2-13

正常工作日:5     工作休息日:2     休息工作日:1

实际工作日:4

From 1992-2-8 to 2010-2-13

正常工作日:4700     工作休息日:2     休息工作日:1

实际工作日:4699

From 1990-2-8 to 2010-2-13

正常工作日:5222     工作休息日:1     休息工作日:0

实际工作日:5221

From 1990-2-8 to 1990-2-13

正常工作日:4     工作休息日:1     休息工作日:0

实际工作日:3

  对比1992-2-8 to 2010-2-13和1990-2-8 to 2010-2-13的结果,发现后者的结果有问题。后者的正确结果应该是5220。时间跨度达到某一个值程序会出现位置错误。一般情况下,工作日的时间跨度不会大于4000多天,所以这个程序还是具有一定实用性和通用性。

银行等单位工作日计算的实现相关推荐

  1. 星期和工作日计算,你会了吗?

    1.计算某个日期是星期几 如下图,是宅男心中的大事记,要计算发生日期是周几,公式为: =WEEKDAY(B2,2) WEEKDAY函数第二参数使用2,用数字1到7表示周一到周日.这个函数在数组计算中经 ...

  2. Java判断工作日计算,计算随意2个日期内的工作日

    当前位置:我的异常网» Java Web开发 » 计算随意2个日期内的工作日 计算随意2个日期内的工作日 www.myexceptions.net  网友分享于:2013-08-17  浏览:51次 ...

  3. c#五个自然日 工作日计算_C#程序输入工作日编号并打印工作日

    c#五个自然日 工作日计算 从工作日编号打印工作日名称 (Printing weekday name from weekday number) A switch statement allows ch ...

  4. java计算工作日_Java工作日计算工具类

    工作日计算工具类 主要功能:传入两个日期,返回这两个日期之间有多少个工作日. 思路: 预先设置好一定年份范围内的节假日.补休到map里.(这里暂时只设置了2017 - 2018年的) 将这个年份范围内 ...

  5. 【SQL开发实战技巧】系列(十四):计算消费后的余额计算银行流水累计和计算各部门工资排名前三位的员工

    系列文章目录 [SQL开发实战技巧]系列(一):关于SQL不得不说的那些事 [SQL开发实战技巧]系列(二):简单单表查询 [SQL开发实战技巧]系列(三):SQL排序的那些事 [SQL开发实战技巧] ...

  6. java 剔除工作日计算超时时间

    剔除工作日计算超时时间 import com.alibaba.fastjson.JSONObject;import java.math.BigDecimal; import java.text.Par ...

  7. 深度复盘我的2020秋招面试,互联网 — 国企/银行 — 事业单位分析的明明白白!

    前言 最近终于忙完了,也结束了招聘,一切尘埃落定. 今天来写帖子 纪念一下我的秋招. 我的秋招可以分为三个阶段吧. 互联网 - 国企/银行 - 事业单位 互联网: 因为自己的算法题实在是刷的太少了,于 ...

  8. 练习-Java顺序结构综合练习一之银行复利计息收益计算

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 题目: 任务: 假定一个用户初始时向一个储蓄帐户中存了 1000 元人民币,年利率为 2.25%.那么月利率为 0.0225/12=0 ...

  9. php工作日,计算工作日(jessie看)-PHP教程,PHP应用

    现在还有问题 周一,周二不能做节假日 可能算法上还有问题,等待你的更新- /** * sports98 * flyruns@hotmail.com (欢迎交流) */ ================ ...

  10. mysql按工作日查询统计优化_工作日计算问题思路和实现

    项目中目前已有一周表存储了一年中所有的假日,给定查询起始日期和结束日期,推导出查询时间段内工作日是多少.为了简化这个问题,需要下面几个假设. 1. 不考虑周六周日,将其视作普通工作日 2. 假日没有交 ...

最新文章

  1. 【Python 】单引号和双引号有什么区别?
  2. 实现将字符串转换为指令执行
  3. 最新的.NET Framework聚焦于改进可访问性
  4. Jsoup 抓取和数据页 认识HTTP头
  5. Activiti的历史记录级别
  6. window下配置定时任务实现类似linux的cron定时任务
  7. javascript入门之私有变量
  8. 骨骼动画编辑器Spine的纹理打包器(texture packer)
  9. java calendar获取年_Java Calendar获取年、月、日、时间,设置年、月、日
  10. YUI:globle object
  11. 网络七层协议和TCP/IP五层协议
  12. 人脸识别技术开发解决方案,人脸识别智慧工地应用开发
  13. linux ui 布局管理器,第1组UI组件:布局管理器
  14. Java 项目的命名规范
  15. hazelcast-management-center安装配置
  16. PCIE 调试过程记录
  17. 微信扫描二维码自动跳转到app下载页面(安卓跳转默认浏览器 苹果跳转苹果商店App Store)
  18. 研报精选230207
  19. iphone上用lua做了个doodlejump的菜单界面
  20. THHP 与 HTTPS 有什么区别?

热门文章

  1. 稳压器功能一览[转]
  2. 趣图:没想到 CSS 深灰色是这样的
  3. 机体坐标系的角速度分量
  4. Kubernetes 中的 requests 和 limits详解
  5. 在闲鱼实习是一种什么样的体验
  6. System.BadImageFormatException: 未能加载文件或程序集
  7. itest考试切屏能检测出来吗_itest测试
  8. 罗格斯的计算机科学博士奖学金,罗格斯大学cs
  9. mysql复制表的两种方法
  10. (转帖)-对乒乓球的思考