分割时间段

来源:互联网 发布:双肩电脑包 知乎 编辑:程序博客网 时间:2024/05/08 20:13

昨天有朋友有这个这样的需求,就是月的划分,是他给定的一个日期,譬如每月的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>>>>>>>>>>>>>>>>>//首段前处理startif (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-xxmBetween =  mBetween - 2;//如果是起始日期在 SPLIT_DAY 前,则固定分段 循环次数+1if (startDate.getDate() < SPLIT_DAY)mBetween ++;//如果是终止日期在 SPLIT_DAY 前,则固定分段 循环次数+1if (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");//测试5Date 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();}}}