工作日處理工具類(包括工作日判斷和工作日區間判斷)

 

對於工作日處理相對來說還是比較簡單的,不外乎就是週末判斷和假期判斷。

 

不過,有些人會把它們寫死在類裏面,看以下代碼:

 

耦合性較強的代碼:

 

 

 

Java代碼 複製代碼 收藏代碼
  1. public class WeekdayUtil {   
  2.   
  3.     /**  
  4.      * @title 判斷兩個日期是否在指定工作日內  
  5.      * @detail (只計算週六和週日)  
  6.      *          例如:前時間2008-12-05,後時間2008-12-11  
  7.      * @author chanson  
  8.      * @param beforeDate 前時間  
  9.      * @param afterDate  後時間  
  10.      * @param deadline 最多相隔時間  
  11.      * @return 是的話,返回true,否則返回false  
  12.      */  
  13.     public boolean compareWeekday(String beforeDate, String afterDate, int deadline) {   
  14.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");   
  15.         try {   
  16.             Date d1 = sdf.parse(beforeDate);   
  17.             Date d2 = sdf.parse(afterDate);   
  18.   
  19.             //工作日   
  20.             int workDay = 0;   
  21.             GregorianCalendar gc = new GregorianCalendar();   
  22.             gc.setTime(d1);   
  23.             // 兩個日期相差的天數   
  24.             long time = d2.getTime() - d1.getTime();   
  25.             long day = time / 3600000 / 24 + 1;   
  26.             if(day < 0){   
  27.                 //如果前日期大於後日期,將返回false   
  28.                 return false;   
  29.             }   
  30.             for (int i = 0; i < day; i++) {   
  31.                 if(isWeekday(gc)){   
  32.                     workDay++;   
  33. //                  System.out.println(gc.getTime());   
  34.                 }   
  35.                 //往後加1天   
  36.                 gc.add(GregorianCalendar.DATE, 1);   
  37.             }   
  38.             return workDay <= deadline;   
  39.         } catch (Exception e) {   
  40.             e.printStackTrace();   
  41.             return false;   
  42.         }   
  43.     }   
  44.        
  45.     /**  
  46.      * @title 判斷是否爲工作日  
  47.      * @detail 工作日計算:  
  48.      *           1、正常工作日,並且爲非假期  
  49.      *           2、週末被調整成工作日  
  50.      * @author chanson  
  51.      * @param date 日期  
  52.      * @return 是工作日返回true,非工作日返回false  
  53.      */  
  54.     public boolean isWeekday(GregorianCalendar calendar){   
  55.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");   
  56.         if (calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SATURDAY   
  57.                 && calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SUNDAY){   
  58.             //平時   
  59.             return !getWeekdayIsHolidayList().contains(sdf.format(calendar.getTime()));   
  60.         }else{   
  61.             //週末   
  62.             return getWeekendIsWorkDateList().contains(sdf.format(calendar.getTime()));   
  63.         }   
  64.     }   
  65.        
  66.     /**  
  67.      * @title 獲取週六和週日是工作日的情況(手工維護)  
  68.      *    注意,日期必須寫全:  
  69.      *       2009-1-4必須寫成:2009-01-04  
  70.      * @author chanson  
  71.      * @return 週末是工作日的列表  
  72.      */  
  73.     public List getWeekendIsWorkDateList(){   
  74.         List list = new ArrayList();   
  75.         list.add("2009-01-04");   
  76.         list.add("2009-01-24");   
  77.         list.add("2009-02-01");   
  78.         list.add("2009-05-31");   
  79.         list.add("2009-09-27");   
  80.         list.add("2009-10-10");   
  81.         return list;   
  82.     }   
  83.        
  84.     /**  
  85.      * @title 獲取週一到週五是假期的情況(手工維護)  
  86.      *    注意,日期必須寫全:  
  87.      *       2009-1-4必須寫成:2009-01-04  
  88.      * @author chanson  
  89.      * @return 平時是假期的列表  
  90.      */  
  91.     public List getWeekdayIsHolidayList(){   
  92.         List list = new ArrayList();   
  93.         list.add("2009-01-29");   
  94.         list.add("2009-01-30");   
  95.         list.add("2009-04-06");   
  96.         list.add("2009-05-01");   
  97.         list.add("2009-05-28");   
  98.         list.add("2009-05-29");   
  99.         list.add("2009-10-01");   
  100.         list.add("2009-10-02");   
  101.         list.add("2009-10-05");   
  102.         list.add("2009-10-06");   
  103.         list.add("2009-10-07");   
  104.         list.add("2009-10-08");   
  105.         return list;   
  106.     }   
  107.   
  108.     public static void main(String[] args) {   
  109.   
  110.         WeekdayUtil dateUtils = new WeekdayUtil();   
  111.         boolean ok = dateUtils.compareWeekday("2009-10-1""2009-10-15"5);   
  112.         System.out.println("是否在五個工作日內:" + ok);   
  113.     }   
  114. }  
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

 

 

 

Java代碼 複製代碼 收藏代碼
  1. <?xml version="1.0" encoding="utf-8"?>   
  2. <root>   
  3.     <validation>   
  4.         <list>   
  5.             <!-- 非補報報文的交易時間必須在5個工作日內 -->   
  6.             <key>EXCH_DATE_CHECK</key>   
  7.             <value>5</value>   
  8.         </list>   
  9.         <list>   
  10.             <!-- 回執處理必須在5個工作日內 -->   
  11.             <key>REC_DATE_CHECK</key>   
  12.             <value>5</value>   
  13.         </list>   
  14.     </validation>   
  15.     <!-- 工作日是假期的情況 -->   
  16.     <weekday>   
  17.         <holiday_list>   
  18.             <date>2009-01-29</date>   
  19.             <date>2009-01-30</date>   
  20.             <date>2009-04-06</date>   
  21.             <date>2009-05-01</date>   
  22.             <date>2009-05-28</date>   
  23.             <date>2009-05-29</date>   
  24.             <date>2009-10-01</date>   
  25.             <date>2009-10-02</date>   
  26.             <date>2009-10-05</date>   
  27.             <date>2009-10-06</date>   
  28.             <date>2009-10-07</date>   
  29.             <date>2009-10-08</date>   
  30.         </holiday_list>   
  31.     </weekday>   
  32.     <!-- 週末是工作日的情況 -->   
  33.     <weekend>   
  34.         <weekday_list>   
  35.             <date>2009-01-04</date>   
  36.             <date>2009-01-24</date>   
  37.             <date>2009-02-01</date>   
  38.             <date>2009-05-31</date>   
  39.             <date>2009-09-27</date>   
  40.             <date>2009-10-10</date>   
  41.         </weekday_list>   
  42.     </weekend>   
  43. </root>  
<?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的方法

 

 

Java代碼 複製代碼 收藏代碼
  1. public class Dom4JUtil {   
  2.        
  3.     private final static String BASE_PATH = "/config/";   
  4.        
  5.     public String getConfFile(String file) {   
  6.         URL confURL = getClass().getClassLoader().getResource(file);   
  7.         if (confURL == null)   
  8.             confURL = getClass().getClassLoader().getResource(   
  9.                     "META-INF/" + file);   
  10.         if (confURL == null)   
  11.             confURL = Thread.currentThread().getContextClassLoader()   
  12.                     .getResource(file);   
  13.         if (confURL == null) {   
  14.             System.err.println(" cann't find config file:-->" + file);   
  15.         } else {   
  16.             String filePath = confURL.getFile();   
  17.             filePath = filePath.replaceAll("%20"" ");   
  18.             File file1 = new File(filePath);   
  19.             if (file1.isFile())   
  20.                 return filePath;   
  21.         }   
  22.         return null;   
  23.     }   
  24.        
  25.     /**  
  26.      * @title 獲取工作日相關配置  
  27.      * @author chanson  
  28.      * @return  
  29.      */  
  30.     public WeekdayVO getWeekdayConfig(){   
  31.            
  32.         Map validateMap = new HashMap();   
  33.         List weekendIsWeekdayList = new ArrayList();   
  34.         List weekdayIsHolidayList = new ArrayList();   
  35.            
  36.         //1、放到web工程   
  37.         File f = new File(getConfFile(BASE_PATH + "weekday.xml"));   
  38.         //2、application測試   
  39.         //String file  = "D:/workspace/test/src/config/weekday.xml";   
  40.         //File f = new File(file);   
  41.         SAXReader reader = new SAXReader();   
  42.         try{   
  43.             Document doc = reader.read(f);   
  44.             Element root = doc.getRootElement();   
  45.                
  46.             //===================================   
  47.             //工作日校驗相關屬性   
  48.             //===================================   
  49.             Element validationElement = root.element("validation");   
  50.             Element listElement;   
  51.             for(Iterator i = validationElement.elementIterator("list");i.hasNext();){   
  52.                 listElement = (Element)i.next();   
  53.                 validateMap.put((String) listElement.elementText("key"),    
  54.                         (String)listElement.elementText("value"));   
  55.             }   
  56.                
  57.             //===================================   
  58.             //工作日是假期的列表   
  59.             //===================================   
  60.             Element weekdayElement = root.element("weekday");   
  61.             Element holidayListElement = weekdayElement.element("holiday_list");   
  62.             Element holidayValueElement = null;   
  63.             for(Iterator i = holidayListElement.elementIterator("date");i.hasNext();){   
  64.                 holidayValueElement = (Element)i.next();   
  65.                 weekdayIsHolidayList.add((String)holidayValueElement.getText());   
  66.             }   
  67.                
  68.             //===================================   
  69.             //週末是工作日的列表   
  70.             //===================================   
  71.             Element weekendElement = root.element("weekend");   
  72.             Element weekdayListElement = weekendElement.element("weekday_list");   
  73.             Element weekdayValueElement = null;   
  74.             for(Iterator i = weekdayListElement.elementIterator("date");i.hasNext();){   
  75.                 weekdayValueElement = (Element)i.next();   
  76.                 weekendIsWeekdayList.add((String)weekdayValueElement.getText());   
  77.             }   
  78.                
  79.             WeekdayVO vo = new WeekdayVO();   
  80.             vo.setValidateMap(validateMap);   
  81.             vo.setWeekdayIsHolidayList(weekdayIsHolidayList);   
  82.             vo.setWeekendIsWeekdayList(weekendIsWeekdayList);   
  83.             return vo;   
  84.         }catch(Exception e){   
  85.             e.printStackTrace();   
  86.             return null;   
  87.         }   
  88.     }   
  89.        
  90.     public static void main(String[] args) {   
  91.         Dom4JUtil dom4JUtil = new Dom4JUtil();   
  92.         WeekdayVO vo = dom4JUtil.getWeekdayConfig();   
  93.         System.out.println(vo.getWeekdayIsHolidayList());   
  94.         System.out.println(vo.getWeekendIsWeekdayList());   
  95.     }   
  96. }  
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類:

 

 

Java代碼 複製代碼 收藏代碼
  1. public class WeekdayVO {   
  2.   
  3.     private Map validateMap;//工作日校驗   
  4.     private List weekendIsWeekdayList;//週末是工作日的列表   
  5.     private List weekdayIsHolidayList;//工作日是假期的列表   
  6.   
  7.        //setter/getter(省略)   
  8. }  
public class WeekdayVO {

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

       //setter/getter(省略)
}

 

 

 

3、修改WeekUtil類中的方法

 

 

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

 

 

Java代碼 複製代碼 收藏代碼
  1. public boolean isWeekday(GregorianCalendar calendar){   
  2.         Dom4JUtil dom4JUtil = new Dom4JUtil();   
  3.         WeekdayVO vo = dom4JUtil.getWeekdayConfig();   
  4.         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");   
  5.         if (calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SATURDAY   
  6.                 && calendar.get(GregorianCalendar.DAY_OF_WEEK) != GregorianCalendar.SUNDAY){   
  7.             //平時   
  8.             return !vo.getWeekdayIsHolidayList().contains(sdf.format(calendar.getTime()));   
  9.         }else{   
  10.             //週末   
  11.             return vo.getWeekendIsWeekdayList().contains(sdf.format(calendar.getTime()));   
  12.         }   
  13.     }  
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)、修改調用方式:

 

 

Java代碼 複製代碼 收藏代碼
  1. public static void main(String[] args) {   
  2.        
  3.     Dom4JUtil dom4JUtil = new Dom4JUtil();   
  4.     Map validateMap = dom4JUtil.getWeekdayConfig().getValidateMap();   
  5.     String EXCH_DATE_CHECK = (String)validateMap.get("EXCH_DATE_CHECK");   
  6.   
  7.     WeekdayUtil dateUtils = new WeekdayUtil();   
  8.     boolean ok = dateUtils.compareWeekday("2009-10-1""2009-10-15", Integer.parseInt(EXCH_DATE_CHECK));   
  9.     System.out.println("是否在五個工作日內:" + ok);   
  10. }  
	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。否則將匹配不上。

 

發佈了5 篇原創文章 · 獲贊 2 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章