银行等单位工作日计算的实现
银行等单位工作日计算的实现
原先想在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.计算某个日期是星期几 如下图,是宅男心中的大事记,要计算发生日期是周几,公式为: =WEEKDAY(B2,2) WEEKDAY函数第二参数使用2,用数字1到7表示周一到周日.这个函数在数组计算中经 ...
- Java判断工作日计算,计算随意2个日期内的工作日
当前位置:我的异常网» Java Web开发 » 计算随意2个日期内的工作日 计算随意2个日期内的工作日 www.myexceptions.net 网友分享于:2013-08-17 浏览:51次 ...
- c#五个自然日 工作日计算_C#程序输入工作日编号并打印工作日
c#五个自然日 工作日计算 从工作日编号打印工作日名称 (Printing weekday name from weekday number) A switch statement allows ch ...
- java计算工作日_Java工作日计算工具类
工作日计算工具类 主要功能:传入两个日期,返回这两个日期之间有多少个工作日. 思路: 预先设置好一定年份范围内的节假日.补休到map里.(这里暂时只设置了2017 - 2018年的) 将这个年份范围内 ...
- 【SQL开发实战技巧】系列(十四):计算消费后的余额计算银行流水累计和计算各部门工资排名前三位的员工
系列文章目录 [SQL开发实战技巧]系列(一):关于SQL不得不说的那些事 [SQL开发实战技巧]系列(二):简单单表查询 [SQL开发实战技巧]系列(三):SQL排序的那些事 [SQL开发实战技巧] ...
- java 剔除工作日计算超时时间
剔除工作日计算超时时间 import com.alibaba.fastjson.JSONObject;import java.math.BigDecimal; import java.text.Par ...
- 深度复盘我的2020秋招面试,互联网 — 国企/银行 — 事业单位分析的明明白白!
前言 最近终于忙完了,也结束了招聘,一切尘埃落定. 今天来写帖子 纪念一下我的秋招. 我的秋招可以分为三个阶段吧. 互联网 - 国企/银行 - 事业单位 互联网: 因为自己的算法题实在是刷的太少了,于 ...
- 练习-Java顺序结构综合练习一之银行复利计息收益计算
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 题目: 任务: 假定一个用户初始时向一个储蓄帐户中存了 1000 元人民币,年利率为 2.25%.那么月利率为 0.0225/12=0 ...
- php工作日,计算工作日(jessie看)-PHP教程,PHP应用
现在还有问题 周一,周二不能做节假日 可能算法上还有问题,等待你的更新- /** * sports98 * flyruns@hotmail.com (欢迎交流) */ ================ ...
- mysql按工作日查询统计优化_工作日计算问题思路和实现
项目中目前已有一周表存储了一年中所有的假日,给定查询起始日期和结束日期,推导出查询时间段内工作日是多少.为了简化这个问题,需要下面几个假设. 1. 不考虑周六周日,将其视作普通工作日 2. 假日没有交 ...
最新文章
- 对 Jenkins+ANT+Jmeter 接口测试的实践
- 自定义起始时间的时间戳计算(个人代码记录)
- java中equals函数所在的类,重写Java中的equals方法介绍
- mysql dns反向解析_Mysql DNS反向解析导致连接超时过程分析(skip-name-resolve)
- 95-38-045-Buffer-UnpooledByteBuf
- 非oracle用户使用expdp,expdp 和impdp使用之一(不同用户和不用表空间)
- eclipse class 中无法打断点
- WPF MVVM 验证
- 微软以75亿美元收购GitHub
- 菜鸟的mybatis实战教程
- 搭建第一个springBoot 摘抄自蚂蚁课堂
- java 经纬度距离_java根据经纬度计算距离
- 《非洲归来 不必远方》读后感
- 最新微信开通状态过滤程序
- 剑客之剑——倚天剑(Vim)
- java+es+nested_Elasticsearch中的关联查询。Nested类型介绍及查询原理。。
- 戏说CAD开发 最简单角度看CAD软件
- 深圳有多强?2928家专精特新中小企业 和 2.1万家高新技术企业!
- java.lang.IllegalArgumentException: Invalid character found in method name [0x160x030x0
- [AGC001E]BBQ Hard