`

工作日处理工具类(包括工作日判断和工作日区间判断)

阅读更多

 

对于工作日处理相对来说还是比较简单的,不外乎就是周末判断和假期判断。

 

不过,有些人会把它们写死在类里面,看以下代码:

 

耦合性较强的代码:

 

 

 

public class WeekdayUtil {

	/**
	 * @title 判断两个日期是否在指定工作日内
	 * @detail (只计算周六和周日)
	 *          例如:前时间2008-12-05,后时间2008-12-11
	 * @author chanson
	 * @param beforeDate 前时间
	 * @param afterDate  后时间
	 * @param deadline 最多相隔时间
	 * @return 是的话,返回true,否则返回false
	 */
	public boolean compareWeekday(String beforeDate, String afterDate, int deadline) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date d1 = sdf.parse(beforeDate);
			Date d2 = sdf.parse(afterDate);

			//工作日
			int workDay = 0;
			GregorianCalendar gc = new GregorianCalendar();
			gc.setTime(d1);
			// 两个日期相差的天数
			long time = d2.getTime() - d1.getTime();
			long day = time / 3600000 / 24 + 1;
			if(day < 0){
				//如果前日期大于后日期,将返回false
				return false;
			}
			for (int i = 0; i < day; i++) {
				if(isWeekday(gc)){
					workDay++;
//					System.out.println(gc.getTime());
				}
				//往后加1天
				gc.add(GregorianCalendar.DATE, 1);
			}
			return workDay <= deadline;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}
	
	/**
	 * @title 判断是否为工作日
	 * @detail 工作日计算:
	 *           1、正常工作日,并且为非假期
	 *           2、周末被调整成工作日
	 * @author chanson
	 * @param date 日期
	 * @return 是工作日返回true,非工作日返回false
	 */
	public boolean isWeekday(GregorianCalendar calendar){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		if (calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SATURDAY
				&& calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SUNDAY){
			//平时
			return !getWeekdayIsHolidayList().contains(sdf.format(calendar.getTime()));
		}else{
			//周末
			return getWeekendIsWorkDateList().contains(sdf.format(calendar.getTime()));
		}
	}
	
	/**
	 * @title 获取周六和周日是工作日的情况(手工维护)
	 *    注意,日期必须写全:
	 *       2009-1-4必须写成:2009-01-04
	 * @author chanson
	 * @return 周末是工作日的列表
	 */
	public List getWeekendIsWorkDateList(){
		List list = new ArrayList();
		list.add("2009-01-04");
		list.add("2009-01-24");
		list.add("2009-02-01");
		list.add("2009-05-31");
		list.add("2009-09-27");
		list.add("2009-10-10");
		return list;
	}
	
	/**
	 * @title 获取周一到周五是假期的情况(手工维护)
	 *    注意,日期必须写全:
	 *       2009-1-4必须写成:2009-01-04
	 * @author chanson
	 * @return 平时是假期的列表
	 */
	public List getWeekdayIsHolidayList(){
		List list = new ArrayList();
		list.add("2009-01-29");
		list.add("2009-01-30");
		list.add("2009-04-06");
		list.add("2009-05-01");
		list.add("2009-05-28");
		list.add("2009-05-29");
		list.add("2009-10-01");
		list.add("2009-10-02");
		list.add("2009-10-05");
		list.add("2009-10-06");
		list.add("2009-10-07");
		list.add("2009-10-08");
		return list;
	}

	public static void main(String[] args) {

		WeekdayUtil dateUtils = new WeekdayUtil();
		boolean ok = dateUtils.compareWeekday("2009-10-1", "2009-10-15", 5);
		System.out.println("是否在五个工作日内:" + ok);
	}
}

 

 

 

   这个类相对来说写得就比较死了——太不遵循OCP原则了吧。

 

   有人说,把工作日配置在数据库中,而且还能根据一定的规律推算出假期来——很厉害,一次生成50年的工作日。但国家

 

的假期是会变的,比如取消5.1长假就是一个很典型的例子,总不至于每次都得改算法吧。搞不准过2年后,连10.1长假都

 

没了。

 

    相对来说,我觉得还是放在XML文件中配置比较灵活。那有人会怀疑说,每次都得访问XML会不会有效率问题。

 

当然,如果你项目中使用它非常频繁的话,那就把数据放在内存中吧。每次修改该XML文件的时候刷新内存就可以了。

 

 

 【改造】

1、引入XML

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<root>
	<validation>
		<list>
			<!-- 非补报报文的交易时间必须在5个工作日内 -->
			<key>EXCH_DATE_CHECK</key>
			<value>5</value>
		</list>
		<list>
			<!-- 回执处理必须在5个工作日内 -->
			<key>REC_DATE_CHECK</key>
			<value>5</value>
		</list>
	</validation>
	<!-- 工作日是假期的情况 -->
	<weekday>
		<holiday_list>
			<date>2009-01-29</date>
			<date>2009-01-30</date>
			<date>2009-04-06</date>
			<date>2009-05-01</date>
			<date>2009-05-28</date>
			<date>2009-05-29</date>
			<date>2009-10-01</date>
			<date>2009-10-02</date>
			<date>2009-10-05</date>
			<date>2009-10-06</date>
			<date>2009-10-07</date>
			<date>2009-10-08</date>
		</holiday_list>
	</weekday>
	<!-- 周末是工作日的情况 -->
	<weekend>
		<weekday_list>
			<date>2009-01-04</date>
			<date>2009-01-24</date>
			<date>2009-02-01</date>
			<date>2009-05-31</date>
			<date>2009-09-27</date>
			<date>2009-10-10</date>
		</weekday_list>
	</weekend>
</root>

 

 

注:该XML文件放在src/config下。

 

2、增加解析XML的方法

 

 

public class Dom4JUtil {
	
	private final static String BASE_PATH = "/config/";
	
	public String getConfFile(String file) {
		URL confURL = getClass().getClassLoader().getResource(file);
		if (confURL == null)
			confURL = getClass().getClassLoader().getResource(
					"META-INF/" + file);
		if (confURL == null)
			confURL = Thread.currentThread().getContextClassLoader()
					.getResource(file);
		if (confURL == null) {
			System.err.println(" cann't find config file:-->" + file);
		} else {
			String filePath = confURL.getFile();
			filePath = filePath.replaceAll("%20", " ");
			File file1 = new File(filePath);
			if (file1.isFile())
				return filePath;
		}
		return null;
	}
	
	/**
	 * @title 获取工作日相关配置
	 * @author chanson
	 * @return
	 */
	public WeekdayVO getWeekdayConfig(){
		
		Map validateMap = new HashMap();
		List weekendIsWeekdayList = new ArrayList();
		List weekdayIsHolidayList = new ArrayList();
		
		//1、放到web工程
		File f = new File(getConfFile(BASE_PATH + "weekday.xml"));
		//2、application测试
		//String file  = "D:/workspace/test/src/config/weekday.xml";
		//File f = new File(file);
		SAXReader reader = new SAXReader();
		try{
			Document doc = reader.read(f);
			Element root = doc.getRootElement();
			
			//===================================
			//工作日校验相关属性
			//===================================
			Element validationElement = root.element("validation");
			Element listElement;
			for(Iterator i = validationElement.elementIterator("list");i.hasNext();){
				listElement = (Element)i.next();
				validateMap.put((String) listElement.elementText("key"), 
						(String)listElement.elementText("value"));
			}
			
			//===================================
			//工作日是假期的列表
			//===================================
			Element weekdayElement = root.element("weekday");
			Element holidayListElement = weekdayElement.element("holiday_list");
			Element holidayValueElement = null;
			for(Iterator i = holidayListElement.elementIterator("date");i.hasNext();){
				holidayValueElement = (Element)i.next();
				weekdayIsHolidayList.add((String)holidayValueElement.getText());
			}
			
			//===================================
			//周末是工作日的列表
			//===================================
			Element weekendElement = root.element("weekend");
			Element weekdayListElement = weekendElement.element("weekday_list");
			Element weekdayValueElement = null;
			for(Iterator i = weekdayListElement.elementIterator("date");i.hasNext();){
				weekdayValueElement = (Element)i.next();
				weekendIsWeekdayList.add((String)weekdayValueElement.getText());
			}
			
			WeekdayVO vo = new WeekdayVO();
			vo.setValidateMap(validateMap);
			vo.setWeekdayIsHolidayList(weekdayIsHolidayList);
			vo.setWeekendIsWeekdayList(weekendIsWeekdayList);
			return vo;
		}catch(Exception e){
			e.printStackTrace();
			return null;
		}
	}
	
	public static void main(String[] args) {
		Dom4JUtil dom4JUtil = new Dom4JUtil();
		WeekdayVO vo = dom4JUtil.getWeekdayConfig();
		System.out.println(vo.getWeekdayIsHolidayList());
		System.out.println(vo.getWeekendIsWeekdayList());
	}
}

 

 

 

使用了一个POJO类:

 

 

public class WeekdayVO {

	private Map validateMap;//工作日校验
	private List weekendIsWeekdayList;//周末是工作日的列表
	private List weekdayIsHolidayList;//工作日是假期的列表

       //setter/getter(省略)
}

 

 

 

3、修改WeekUtil类中的方法

 

 

   1)、修改工作日判断方法:

 

 

public boolean isWeekday(GregorianCalendar calendar){
		Dom4JUtil dom4JUtil = new Dom4JUtil();
		WeekdayVO vo = dom4JUtil.getWeekdayConfig();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		if (calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SATURDAY
				&& calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SUNDAY){
			//平时
			return !vo.getWeekdayIsHolidayList().contains(sdf.format(calendar.getTime()));
		}else{
			//周末
			return vo.getWeekendIsWeekdayList().contains(sdf.format(calendar.getTime()));
		}
	}

 

 

 

 2)、修改调用方式:

 

 

	public static void main(String[] args) {
		
		Dom4JUtil dom4JUtil = new Dom4JUtil();
		Map validateMap = dom4JUtil.getWeekdayConfig().getValidateMap();
		String EXCH_DATE_CHECK = (String)validateMap.get("EXCH_DATE_CHECK");

		WeekdayUtil dateUtils = new WeekdayUtil();
		boolean ok = dateUtils.compareWeekday("2009-10-1", "2009-10-15", Integer.parseInt(EXCH_DATE_CHECK));
		System.out.println("是否在五个工作日内:" + ok);
	}

 

 

 

   改造完毕。

 

 

   更高级的改造

 

    对于我现在的项目来说,算是完成了。当然还可以改得更好一些:

 

1、扩展XML,区分每年的工作日。(对于某些统计分析的项目,可能会用得着)

 

2、添加可视化页面配置,避免了人工修改配置文件。

 

3、目前的XML文件中的日期格式有要求:

 

必须补全10位。例如:2008-1-1 必须配置成 2008-01-01。否则将匹配不上。

 

 

 

 

 

 

2
0
分享到:
评论

相关推荐

    自己封装的DateUtils工具类

    在Java编程中,DateUtils工具类是一个非常实用的辅助类,它封装了各种日期和时间处理的方法,大大简化了开发者在处理日期时的工作。这里我们深入探讨一下自定义的DateUtils工具类及其重要功能。 首先,`DateUtils`...

    js-实现多功能时间日期时间段区间时间日期插件.rar

    "js-实现多功能时间日期时间段区间时间日期插件.rar" 提供了一个高效、易用的解决方案,旨在简化前端开发者的工作。这款jQuery时间日期插件允许用户方便地选择和操作时间、日期以及时间段,极大地提高了交互体验。 ...

    Time4J高级时间和日期处理Java库

    此外,`Cycle`类允许创建和处理重复的日期时间模式,如每周二或每月最后一个星期五。 **4. 高级日期时间计算** Time4J提供了强大的日期时间计算功能,如闰年、闰秒、儒略日、伊斯兰历、希伯来历等的处理。通过`...

    Python-基于gitcommit生成时间计算自己的加班时长

    4. **定义工作时间和加班时间**:设置正常工作日和周末的工作时间范围,例如工作日9:00到18:00,然后判断每个提交是否在这些范围内。 5. **计算加班时长**:根据提交时间与工作时间的比较,计算超出部分的时间,并...

    xk-time Java时间工具包.zip

    "XK-Time Java时间工具包"是一个专门为Java开发者设计的库,旨在简化和增强Java标准库中的日期和时间处理功能。这个工具包提供了更高效、更直观的方式来操作和格式化日期、时间以及时间间隔,使得在Java项目中处理...

    unix时间戳转换查询小工具

    这个“Unix时间戳转换查询小工具”显然是为了帮助开发者和用户方便地处理和转换Unix时间戳。 Unix时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不包括闰秒。这个时间点被称为“Unix纪元”。在编程中...

    CIsSession - 用于设置时间间隔的类 (时段) - MetaTrader 5程序库.zip

    这对于交易策略有着重要的意义,例如,某些交易者可能只在特定的市场开放时间进行交易,或者某些操作只在工作日的特定时间段执行。通过使用此类,开发者可以轻松地实现这些需求。 首先,我们需要了解MetaTrader 5中...

    Excel横道图绘制插件

    - **日期和时间处理**:甘特图涉及大量的日期计算,需要理解日期对象的使用,以及如何处理闰年、工作日和非工作日等复杂情况。 - **图形渲染**:学习如何在Excel中绘制图形,包括线条、矩形和其他形状,以表示任务和...

    电子政务-大范围、高精度区间式电压表.zip

    区间式电压表的数据采集和处理,往往与电力信息系统紧密相连。通过集成先进的传感器技术和数据通信技术,区间式电压表能够实时将测量数据传输至中央管理系统,进行大数据分析,为决策者提供实时、准确的电力运行情况...

    营销员时间调查表格式.doc

    在调查表的各个时间区间内,列出了可能的活动类别,包括“准备·整理”、“移动”、“商谈”、“休息”和其他未明确指定的任务。这些分类涵盖了营销员日常工作的主要环节: 1. **准备·整理**:这部分可能包括制定...

    课程excell函数大全.pdf

    EDATE添加或减去指定月数,EOMONTH返回指定月份的最后一天,HOUR、MINUTE和SECOND用于提取时间的小时、分钟和秒,其他还包括NETWORKDAYS计算工作日数,NOW获取当前日期和时间,TIME、TIMEVALUE、TODAY、WEEKDAY、...

    Android-Klock是Kotlin1.3的多平台日期和时间处理库

    Klock是一个针对Kotlin 1.3设计的高效、灵活的日期和时间处理库,它为Android开发者提供了一种在不同平台上(包括Android)统一处理时间的解决方案。这个库特别适合那些希望在Android、iOS以及JVM之间共享代码的跨...

    Python库 | Dtime-0.1-py3-none-any.whl

    1. **高级日期和时间类**:Dtime库可能扩展了Python的标准datetime模块,提供更加灵活的日期和时间对象,可以方便地进行日期加减、比较、区间判断等操作。 2. **时间格式化和解析**:除了标准库提供的strftime和...

    py代码-判断是否在范围时间内

    例如,我们可能需要检查一个事件是否发生在一个指定的小时区间内,或者验证用户提交的数据是否在工作日的工作时间内。在这个场景中,`main.py` 文件可能包含了实现这一功能的代码。 首先,让我们探讨Python中的时间...

    Ruby-timelord为时间类添加一些扩展功能

    总的来说,`time-lord`是Ruby开发者处理日期和时间时的一个强大工具,它以更加人性化的方式呈现时间信息,使得代码更加易读,同时简化了时间相关的编程工作。通过熟练掌握和运用这个库,你的Ruby项目将在时间和日期...

    matlab开发-softwarespartanDateTime

    2. **日期时间计算**:除了MATLAB内置的日期时间运算,这个工具箱可能提供了更复杂的日期时间运算,比如业务日期计算(不包括周末或节假日)、时间区间统计等。 3. **时间序列分析**:对于金融、科学或工程领域的...

    期末考计算机审计.doc

    8. **审计工作底稿**:实验要求完成审计工作底稿,这是审计过程的重要记录,包含了所有审计活动的详细记录,包括审计程序、发现的问题、审计结论等,为审计报告的编写提供基础。 通过以上知识点,我们可以看出...

    基于决策树理论的交通流参数短时预测_薛红军1

    此外,模型在工作日和周末数据上分别建模,显著提升了预测性能,反映了交通模式随时间的差异。 在不同速度区间下,模型在各等级道路的中速区间的预测结果最为稳定且准确。这表明,对于交通流参数的短期预测,结合...

    机械设备(电子机械设备)类工具配件行业电动砂光机领域分析报告(研究报告).pdf

    《机械设备(电子机械设备)类工具配件行业电动砂光机领域分析报告》 这份报告深入剖析了电动砂光机在机械设备,特别是电子机械设备行业的应用和发展状况。电动砂光机作为工具配件的重要组成部分,其性能和质量直接...

Global site tag (gtag.js) - Google Analytics