分割时间段

昨天有朋友有这个这样的需求,就是月的划分,是他给定的一个日期,譬如每月的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();
		}
	}
}


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