分割時間段

昨天有朋友有這個這樣的需求,就是月的劃分,是他給定的一個日期,譬如每月的21號爲一個分段點,意思是 2013-06-21 到 2013-07-20 爲一時間段,2013-07-21 到 2013-08-20 爲另一段。那麼需要用這個規則去分割他給出的時間段(譬如拆分 2012-01-01 到2013-01-01)

寫了個邏輯,反反覆覆,弄了大半天,記下源碼,以備不時之需。

package com.jy.action.bases;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Map.Entry;

public class SplitDateTest2 {
	private final static int SPLIT_DAY = 21;//要切割的時間點,或者叫分段點
	
	/**
	 * @deprecated 分段邏輯是:單獨處理段頭和段位,中間工整的段就是循環處理。
	 * @param startDate 時間段的開始時間
	 * @param endDate 時間段的結束時間
	 */
	public TreeMap<Date, Date> splidDate(Date startDate, Date endDate){
		TreeMap<Date, Date> dateMap = new TreeMap<Date, Date>();
		//判斷 startDate 是否大於 endDate,如果大於就 不作處理。
		if(startDate.compareTo(endDate) > 0){
			//此處應該改爲 log輸出信息
			//System.out.println("startDate("+startDate.toLocaleString()+") 需要小於 endDate("+endDate.toLocaleString()+")");
			return dateMap;
		}
		
		
		//計算 startDate 與 endDate 相差多少個月
		int mBetween = (endDate.getYear() - startDate.getYear())*12 + endDate.getMonth() - startDate.getMonth();
		
		//根據startDate和分段點生成分段時間
		Calendar splitDate = Calendar.getInstance();
		splitDate.setTime(startDate);
		splitDate.set(Calendar.DATE, SPLIT_DAY);
		
		//根據startDate和分段點生成分段時間的最後一天的時間。
		Calendar splitDateEnd = Calendar.getInstance();		
		splitDateEnd.setTime(startDate);
		splitDateEnd.set(Calendar.DATE, SPLIT_DAY - 1);
		
		
		// 不需要分段start>>>>>>>>>>>>>>
		if (mBetween == 0 && (startDate.getDate() >= SPLIT_DAY || endDate.getDate() < SPLIT_DAY)){
			dateMap.put(startDate, endDate);
			return dateMap;
		}
		// 不需要分段end<<<<<<<<<<<<<<<<
		
		//需要分段start>>>>>>>>>>>>>>>>>
		
		//首段前處理start
		if (startDate.getDate() < SPLIT_DAY){
			dateMap.put(startDate, splitDateEnd.getTime());
			splitDateEnd.set(Calendar.MONTH, splitDateEnd.get(Calendar.MONTH) + 1);
		}else{
			splitDateEnd.set(Calendar.MONTH, splitDateEnd.get(Calendar.MONTH) + 1);
			dateMap.put(startDate, splitDateEnd.getTime());
		}
		//首段前處理end
		
		//分段s前處理start>>>>>>>>>
		//計算 固定的分段, 給後面的固定分段循環用
		//固定的要分的段 例如 2013-06-xx到 2013-09-xx  mBetween=3 
		//所以一定會有mBetween-2=1個固定的或標準的分段,也就是 2013-07-xx到 2013-08-xx
		mBetween =  mBetween - 2;
		
		//如果是起始日期在 SPLIT_DAY 前,則固定分段 循環次數+1
		if (startDate.getDate() < SPLIT_DAY)
			mBetween ++;
		
		//如果是終止日期在 SPLIT_DAY 前,則固定分段 循環次數+1
		if (endDate.getDate() >= SPLIT_DAY)
			mBetween ++;
		//分段s前處理end<<<<<<<<<<<
		
		if (startDate.getDate() < SPLIT_DAY){
			for (int i=1; i<=mBetween; i++){
				dateMap.put(splitDate.getTime(), splitDateEnd.getTime());
				splitDate.set(Calendar.MONTH, splitDate.get(Calendar.MONTH) + 1);
				splitDateEnd.set(Calendar.MONTH, splitDateEnd.get(Calendar.MONTH) + 1);
			}
		}else{
			for (int i=1; i<=mBetween; i++){
				splitDate.set(Calendar.MONTH, splitDate.get(Calendar.MONTH) + 1);
				splitDateEnd.set(Calendar.MONTH, splitDateEnd.get(Calendar.MONTH) + 1);
				dateMap.put(splitDate.getTime(), splitDateEnd.getTime());
			}
			splitDate.set(Calendar.MONTH, splitDate.get(Calendar.MONTH) + 1);//這屬於末段處理邏輯
		}
		
		dateMap.put(splitDate.getTime(), endDate);//這屬於末段處理
		//需要分段end<<<<<<<<<<<<<<
		
		return dateMap;
	}
	
	public static void main(String[] args) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			//測試1
//			Date startDate = sdf.parse("2013-02-12");
//			Date endDate = sdf.parse("2013-08-13");
			//測試2
//			Date startDate = sdf.parse("2013-02-12");
//			Date endDate = sdf.parse("2013-08-23");
			//測試3
//			Date startDate = sdf.parse("2013-02-22");
//			Date endDate = sdf.parse("2013-08-13");
			//測試4
//			Date startDate = sdf.parse("2013-02-22");
//			Date endDate = sdf.parse("2013-08-23");
			//測試5
			Date startDate = sdf.parse("2013-01-12");
			Date endDate = sdf.parse("2013-06-23");
			
			SplitDateTest2 sdt = new SplitDateTest2();
			TreeMap<Date, Date> dateMap = sdt.splidDate(startDate, endDate);

			Iterator<Entry<Date, Date>>  it = dateMap.entrySet().iterator();
			
			Entry<Date, Date> entry;
			while(it.hasNext()){
				entry = it.next();
				System.out.println(entry.getKey().toLocaleString()+"到"+entry.getValue().toLocaleString());
			}
			
			
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章