关于日期处理的工具类

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.seeyon.v3x.common.i18n.ResourceBundleUtil;
import com.seeyon.v3x.common.web.login.CurrentUser;

/**
 * 日期操作
 * 
 * <pre>
 *  e.g
 *  将字符串转成日期
 *  Datetimes.parseDate(&quot;2005-01-21&quot;)	= Fri Jan 21 00:00:00 CST 2005
 *  Datetimes.parseDatetime(&quot;2005-01-21 12:04:33&quot;) = Fri Jan 21 00:00:00 CST 2005
 *  
 *  将日期格式化输出
 *  Datetimes.formatDate(new Date()) = 2007-03-19
 *  Datetimes.formatDatetime(new Date()) =2007-03-19 11:18:14
 *      
 *  取得特殊日期
 *  1	得到指定日期所在周的第一天的日期
 *  java.util.Date  date = Datetimes.getFirstDayInWeek(date);
 * 
 *  2	得到指定日期所在周的周末的日期
 *  java.util.Date  date = Datetimes.getLastDayInWeek(date);
 * 
 *  3	得到指定日期所在月的第一天的日期
 *  java.util.Date  date = Datetimes.getFirstDayInMonth(date);
 * 
 *  4	得到指定日期所在月的最后一天的日期
 *  java.util.Date  date = Datetimes.getLastDayInMonth(date);
 * 
 *  5	得到指定日期所在季度的第一天的日期
 *  java.util.Date  date = Datetimes.getFirstDayInSeason(date);
 * 
 *  6	得到指定日期所在季度的最后一天的日期
 *  java.util.Date  date = Datetimes.getLastDayInSeason(date);
 * 
 *  7	得到指定日期所在年度的第一天的日期
 *  java.util.Date  date = Datetimes.getFirstDayInYear(date);
 * 
 *  8	得到指定日期所在年度的最后一天的日期
 *  java.util.Date  date = Datetimes.getLastDayInYear(date);
 *  
 *  9	取得下一个周期的时间
 *  Datetimes.getNextPeriodMinute(new Date(), 30, true)
 * 
 * </pre>
 * 
 * @author <a href="mailto:[email protected]">Tanmf</a>
 * @version 1.0 2006-10-8
 */
public final class Datetimes {
	private static final Log logger = LogFactory.getLog(Datetimes.class);
	
	public static final String datetimeStyle = "yyyy-MM-dd HH:mm:ss";

	public static final String dateStyle = "yyyy-MM-dd";

    public static final String dateStyleWithoutYear = "MM-dd";

    public static final String datetimeStartWithMonthStyle = "MM-dd HH:mm";
    
	public static final String datetimeWithoutSecondStyle = "yyyy-MM-dd HH:mm";

	private static final int[] seasonFirstMonth = new int[] { 0, 0, 0, 3, 3, 3, 6, 6, 6, 9, 9, 9 };

	private static final int[] seasonLastMonth = new int[] { 2, 2, 2, 5, 5, 5, 8, 8, 8, 11, 11, 11 };
  
	/**
	 * 得到指定日期所在周的第一天的日期, 时分为00:00:00
	 * 
	 * @param date
	 * @param locale
	 * @return
	 */
	public static Date getFirstDayInWeek(Date date, Locale locale) {
		GregorianCalendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);
		int firstDayOfWeek = calendar.getFirstDayOfWeek();// 一周的第一天是星期几

		int week = calendar.get(Calendar.DAY_OF_WEEK);// 当前是星期几, 1表示星期日

		int dayOfWeek = 0; // 当前是这周的第几天
		if (firstDayOfWeek == week) {// 当前是这周的第一天
			dayOfWeek = 1;
		}
		else if (firstDayOfWeek > week) {
			dayOfWeek = 7 - week + firstDayOfWeek - 1;
		}
		else if (firstDayOfWeek < week) {
			dayOfWeek = week - firstDayOfWeek + 1;
		}

		calendar.add(Calendar.DAY_OF_WEEK, 1 - dayOfWeek);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 得到指定日期所在周的第一天的日期, 时分为00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayInWeek(Date date) {
		return getFirstDayInWeek(date, Locale.getDefault());
	}

	/**
	 * 得到指定日期所在周的周末的日期, 时分为23:59:59
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayInWeek(Date date, Locale locale) {
		GregorianCalendar calendar = new GregorianCalendar(locale);
		calendar.setTime(date);

		int firstDayOfWeek = calendar.getFirstDayOfWeek();// 一周的第一天是星期几
		int week = calendar.get(Calendar.DAY_OF_WEEK);// 当前是星期几

		int dayOfWeek = 0; // 当前是这周的第几天

		if (firstDayOfWeek == week) {// 当前是这周的第一天
			dayOfWeek = 1;
		}
		else if (firstDayOfWeek > week) {
			dayOfWeek = 7 - week + firstDayOfWeek - 1;
		}
		else if (firstDayOfWeek < week) {
			dayOfWeek = week - firstDayOfWeek + 1;
		}

		calendar.add(Calendar.DAY_OF_WEEK, 7 - dayOfWeek);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 得到指定日期所在周的周末的日期, 时分为23:59:59
	 * 
	 * @param date
	 * @param locale
	 * @return
	 */
	public static Date getLastDayInWeek(Date date) {
		return getLastDayInWeek(date, Locale.getDefault());
	}

	/**
	 * 得到指定日期所在月的第一天的日期, 时分为00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayInMonth(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);

		int day = calendar.getActualMinimum(Calendar.DATE);
		calendar.set(Calendar.DATE, day);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 得到指定日期所在月的最后一天的日期, 时分为23:59:59
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayInMonth(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);

		int day = calendar.getActualMaximum(Calendar.DATE);
		calendar.set(Calendar.DATE, day);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return calendar.getTime();
	}

	/**
	 * 得到指定日期所在季度的第一天的日期, 时分为00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayInSeason(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);

		int currentMonth = calendar.get(Calendar.MONTH);

		calendar.set(Calendar.MONTH, seasonFirstMonth[currentMonth]);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return getFirstDayInMonth(calendar.getTime());
	}

	/**
	 * 得到指定日期所在季度的最后一天的日期, 时分为23:59:59
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayInSeason(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);

		int currentMonth = calendar.get(Calendar.MONTH);

		calendar.set(Calendar.MONTH, seasonLastMonth[currentMonth]);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return getLastDayInMonth(calendar.getTime());
	}

	/**
	 * 得到指定日期所在年度的第一天的日期, 时分为00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayInYear(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);

		calendar.set(Calendar.MONTH, calendar.getActualMinimum(Calendar.MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return getFirstDayInMonth(calendar.getTime());
	}

	/**
	 * 得到指定日期所在年度的最后一天的日期, 时分为23:59:59
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDayInYear(Date date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);

		calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);

		return getLastDayInMonth(calendar.getTime());
	}
	
	/**
	 * 得到今天开始的时间 2008-08-08 00:00:00
	 * 
	 * @return
	 */
	public static Date getTodayFirstTime(){
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);
        
        return calendar.getTime();
	}
	
	/**
	 * 得到指定天开始的时间2008-08-08 00:00:00
	 * 
	 * @param date
	 * @return
	 */
	public static Date getTodayFirstTime(Date date){
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);
        
        return calendar.getTime();
	}
	
	/**
	 * 得到指定天开始的时间2008-08-08 00:00:00
	 * 
	 * @param dateStr yyyy-MM-dd
	 * @return
	 */
	public static Date getTodayFirstTime(String dateStr){
		return getTodayFirstTime(parse(dateStr, dateStyle));
	}
	
	/**
	 * 得到今天结束的时间 2008-08-08 23:59:59
	 * 
	 * @return
	 */
	public static Date getTodayLastTime(){
		Calendar calendar = new GregorianCalendar();
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);
        
        return calendar.getTime();
	}
	
	/**
	 * 得到指定天结束的时间 2008-08-08 23:59:59
	 * 
	 * @param date 
	 * @return
	 */
	public static Date getTodayLastTime(Date date){
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY));
		calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE));
		calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		calendar.set(Calendar.MILLISECOND, 0);
        
        return calendar.getTime();
	}
	
	/**
	 * 得到指定天结束的时间 2008-08-08 23:59:59
	 * 
	 * @param dateStr yyyy-MM-dd
	 * @return
	 */
	public static Date getTodayLastTime(String dateStr){
		return getTodayLastTime(parse(dateStr, dateStyle));
	}

	/**
	 * 将日期转成字符串,格式为yyyy-MM-dd HH:mm:ss
	 * 
	 * @param datetime
	 * @return
	 */
	public static String formatDatetime(Date datetime) {
		return format(datetime,	datetimeStyle);
	}
	
	/**
	 * 将日期转成字符串,格式为yyyy-MM-dd HH:mm
	 * 
	 * @param datetime
	 * @return
	 */
	public static String formatDatetimeWithoutSecond(Date datetime){
		return format(datetime,	datetimeWithoutSecondStyle);
	}

	/**
	 * 将日期转成字符串,格式为yyyy-MM-dd
	 * 
	 * @param date
	 * @return
	 */
	public static String formatDate(Date date) {
    	if(date == null){
    		return null;
    	}
    	
		return format(date,	dateStyle);
	}
	
	/**
	 * 将日期转成字符串, 指定显示格式
	 * 
	 * @param date
	 * @param pattern
	 * @return
	 */
    public static String format(Date date, String pattern) {
    	if(date == null){
    		return null;
    	}
    	
        return DateFormatUtils.format(date, pattern);
    }
    
    /**
     * 将日期转成字符串, 指定显示格式
     * 
     * @param date
     * @param pattern
     * @param locale
     * @return
     */
    public static String format(Date date, String pattern, Locale locale) {
    	if(date == null){
    		return null;
    	}
    	
        return DateFormatUtils.format(date, pattern, locale);
    }
    
    /**
     * 将日期转成字符串, 指定显示格式,并转换成指定区域的时区
     * 
     * @param date
     * @param pattern
     * @param zone
     * @return
     */
    public static String format(Date date, String pattern, TimeZone zone) {
    	if(date == null){
    		return null;
    	}
    	
        return DateFormatUtils.format(date, pattern, zone);
    }
    
    /**
     * 将日期转成字符串, 指定显示格式
     * 
     * @param date
     * @param pattern
     * @param zone
     * @param locale
     * @return
     */
    public static String format(Date date, String pattern, TimeZone zone, Locale locale) {
    	if(date == null){
    		return null;
    	}
    	
        return DateFormatUtils.format(date, pattern, zone, locale);
    }
    
    /**
     * 格式化为日期或者日期+时间, 判别依据是:时、分、秒、毫秒都为0
     * 
     * @param date
     * @return
     */
    public static String formatDateOrDatetime(Date date){
    	if(date == null){
    		return null;
    	}
    	
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		
		if(calendar.get(Calendar.HOUR_OF_DAY) == 0 
			&& calendar.get(Calendar.MINUTE) == 0 
			&& calendar.get(Calendar.SECOND) == 0 
			&& calendar.get(Calendar.MILLISECOND) == 0 
		){
			return formatDate(date);
		}
		
    	return formatDatetime(date);
    }

	/**
	 * 将字符串转成日期
	 * 
	 * @param datetime
	 *            格式为yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static Date parseDatetime(String datetime) {
		return parse(datetime, TimeZone.getDefault(), datetimeStyle);
	}

	/**
	 * 将字符串转成日期
	 * 
	 * @param date
	 *            格式为yyyy-MM-dd
	 * @return
	 */
	public static Date parseDate(String date) {
		return parse(date, TimeZone.getDefault(), dateStyle);
	}

	/**
	 * 将字符串转换成Date类型,配置前端时间选择器使用
	 * 
	 * @param date
	 *            格式为yyyy-MM-dd HH:mm
	 * @return
	 */
	public static Date parseDatetimeWithoutSecond(String date) {
		return parse(date, TimeZone.getDefault(), datetimeWithoutSecondStyle);
	}
	
	/**
	 * 将字符串按照指定的格式转换成日期
	 * 
	 * @param dateStr
	 * @param patterns 格式,如yy-MM-dd HH:mm:ss,可以不设定,默认三种格式:yyyy-MM-dd HH:mm,yyyy-MM-dd,yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static Date parse(String dateStr, String... patterns){
		return parse(dateStr, TimeZone.getDefault(), patterns);
	}
	
	/**
	 * 将字符串按照指定的格式转换成日期,采用系统默认语言
	 * 
	 * @param dateStr
	 * @param pattern 格式,如yy-MM-dd HH:mm:ss,可以不设定,默认三种格式:yyyy-MM-dd HH:mm,yyyy-MM-dd,yyyy-MM-dd HH:mm:ss
	 * @return
	 */
	public static Date parse(String dateStr, TimeZone timeZone, String... patterns){
		if (Strings.isBlank(dateStr)) {
			return null;
		}
		
		String[] parsePatterns = {dateStyle, datetimeWithoutSecondStyle, datetimeStyle};
		
		if(patterns != null && patterns.length > 0){
			String[] p = new String[parsePatterns.length + patterns.length];	
			System.arraycopy(patterns, 0, p, 0, patterns.length);
			System.arraycopy(parsePatterns, 0, p, patterns.length, parsePatterns.length);
			parsePatterns = p;
		}
		
		try {
	        SimpleDateFormat parser = null;
	        ParsePosition pos = new ParsePosition(0);
	        
	        for (int i = 0; i < parsePatterns.length; i++) {
	            if (i == 0) {
    				parser = new SimpleDateFormat(parsePatterns[0]);
	            	
	    			if(timeZone != null){
	    				parser.setTimeZone(timeZone);
	    			}
	            }
	            else {
	                parser.applyPattern(parsePatterns[i]);
	            }
	            
	            pos.setIndex(0);
	            Date date = parser.parse(dateStr, pos);
	            
	            if (date != null && pos.getIndex() == dateStr.length()) {
	                return date;
	            }
	        }
		}
		catch (Exception e) {
			logger.error("", e);
		}
		
		return null;
	}
	
	/**
	 * 在指定的日期基础上移动秒数,分、时、日、月、年自动变化
	 * 
	 * @param date
	 * @param amount 移动秒数,负数表示往回倒
	 * @return
	 */
	public static Date addSecond(Date date, int amount){
		return add(date, Calendar.SECOND, amount);
	}
	
	/**
	 * 在指定的日期基础上移动分数,时、日、月、年自动变化
	 * 
	 * @param date
	 * @param amount 移动分数,负数表示往回倒
	 * @return
	 */
	public static Date addMinute(Date date, int amount){
		return add(date, Calendar.MINUTE, amount);
	}
	
	/**
	 * 在指定的日期基础上移动小时数,日、月、年自动变化,采用24小时制
	 * 
	 * @param date
	 * @param amount 移动小时数,负数表示往回倒
	 * @return
	 */
	public static Date addHour(Date date, int amount){
		return add(date, Calendar.HOUR_OF_DAY, amount);
	}
	
	/**
	 * 在指定的日期基础上移动天数,月份、年份自动变化
	 * e.g
	 * <pre>
	 * Datetimes.addDate(new Date(), -1)	= 昨天
	 * Datetimes.addDate(new Date(), 1)	= 明天
	 * </pre>
	 * @param date
	 * @param amount 移动天数,负数表示往回倒
	 * @return
	 */
	public static Date addDate(Date date, int amount){
		return add(date, Calendar.DATE, amount);
	}
	
	/**
	 * 在指定的日期基础上移动月份,年份自动变化
	 * 
	 * @param date
	 * @param amount 移动月数,负数表示往回倒
	 * @return
	 */
	public static Date addMonth(Date date, int amount){
		return add(date, Calendar.MONTH, amount);
	}
	
	/**
	 * 在指定的日期基础上移动年份
	 * 
	 * @param date
	 * @param amount 移动年数,负数表示往回倒
	 * @return
	 */
	public static Date addYear(Date date, int amount){
		return add(date, Calendar.YEAR, amount);
	}
	
	private static Date add(Date date, int field, int amount){
		if(amount == 0){
			return date;
		}
		
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		
		calendar.add(field, amount);
		
		return calendar.getTime();
	}
	
	/**
	 * 检测时间点是否在时间段之内<br>
	 * e.g.
	 * <pre>
	 * Datetimes.between(new Date(107, 8, 8), new Date(107, 1, 1), new Date(107, 12, 31), true)  : true
	 * Datetimes.between(new Date(107, 1, 1), new Date(107, 1, 1), new Date(107, 12, 31), true)  : true
	 * Datetimes.between(new Date(107, 1, 1), new Date(107, 1, 1), new Date(107, 12, 31), false) : false
	 * </pre>
	 * @param checkupDate
	 *            要检查的时间点
	 * @param startDate
	 *            时间段的开始时间
	 * @param endDate
	 *            时间段的结束时间
	 * @param isIncludeBorderline
	 *            检测时是否包含边界时间,true:表示被检测的时间点可以等于时间段的起止时间点
	 * @return true: 被检测的时间点在时间短内
	 */
	public static boolean between(Date checkupDate, Date startDate,
			Date endDate, boolean isIncludeBorderline) {
		if (!startDate.before(endDate)) {
			Date temp = startDate;
			startDate = endDate;
			endDate = temp;
		}

		if (checkupDate.after(startDate) && checkupDate.before(endDate)) {
			return true;
		}

		if (isIncludeBorderline
				&& (checkupDate.equals(startDate) || checkupDate.equals(endDate))) {
			return true;
		}

		return false;
	}
	
	/**
	 * 判断两个时间段是否有叠加<br>
	 * e.g.
	 * <pre>
	 * Datetimes.checkOverup(new Date(107, 1, 1), new Date(107, 12, 31), new Date(107, 12, 31), new Date(108, 12, 31), true)  : false
	 * Datetimes.checkOverup(new Date(107, 1, 1), new Date(107, 12, 31), new Date(107, 12, 31), new Date(108, 12, 31), false) : true
	 * Datetimes.checkOverup(new Date(107, 1, 1), new Date(107, 12, 31), new Date(108, 1, 1), new Date(108, 12, 31), false)   : false
	 * </pre>
	 * @param startDate1
	 *            时间段1的开始时间
	 * @param endDate1
	 *            时间段1的结束时间
	 * @param startDate2
	 *            时间段2的开始时间
	 * @param endDate2
	 *            时间段2的结束时间
	 * @param allowIncludeBorderline
	 *            检测时是否允许边界时间重叠,true:时间段1的结束时间可以等于时间段2的开始时间
	 * @return true: 两个时间短有叠加
	 */
	public static boolean checkOverup(Date startDate1, Date endDate1,
			Date startDate2, Date endDate2, boolean allowIncludeBorderline) {
		if (!startDate1.before(endDate1)) {
			Date temp = startDate1;
			startDate1 = endDate1;
			endDate1 = temp;
		}
		if (!startDate2.before(endDate2)) {
			Date temp = startDate2;
			startDate2 = endDate2;
			endDate2 = temp;
		}

		if (endDate1.before(startDate2) || endDate2.before(startDate1)) {
			return false;
		}
		
		if(allowIncludeBorderline && (endDate1.equals(startDate2) || endDate2.equals(startDate1))){
			return false;
		}

		return true;
	}
	
	/**
	 * 取得下一个周期的时间
	 * <pre>
	 * Datetimes.getNextPeriodMinute(new Date(), 30, true)
	 * 若当前是:2007-06-23 12:18:25 返回值 2007-06-23 12:30:00
	 * 若当前是:2007-06-23 12:30:25 返回值 2007-06-23 13:00:00
	 * 
	 * Datetimes.getNextPeriodMinute(new Date(), 10, true)
	 * 若当前是:2007-06-23 12:18:25 返回值 2007-06-23 12:20:00
	 * 若当前是:2007-06-23 12:50:25 返回值 2007-06-23 13:00:00
	 * </pre>
	 * @param date
	 * @param period 时间间隔,如15、30,用于将一个小时却分乘若干段
	 * @param clearSecond 是否将秒清0
	 * @return
	 */
	public static Date getNextPeriodMinute(Date date, int period, boolean clearSecond){
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		if(clearSecond){
			calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND));
		}
		int minute = calendar.get(Calendar.MINUTE);
		int newMinute = 0;
		int i = 0;
		while(true) {
			newMinute = (i++) * period;
			if(newMinute > minute){
				break;
			}
		}
		
		int amount = newMinute - minute;
		
		calendar.add(Calendar.MINUTE, amount);
		
		return calendar.getTime();
	}
	
	/**
	 * 将地区的时间转换成服务器的时间
	 * 
	 * <pre>
	 * 服务器在GMT+08:00 东8区
	 * conversionToServerDate(Date(2007-06-29 17:20:27), TimeZone.getTimeZone("GMT+09:00")) : 2007-06-29 16:20:27
	 * conversionToServerDate(Date(2007-06-29 17:20:27), TimeZone.getTimeZone("GMT+00:00")) : 2007-06-30 01:20:27
	 * </pre>
	 * 
	 * @param localDate
	 *            地方时间
	 * @param localZone
	 *            客户端所在的时区
	 * @return
	 */
	public static Date conversionToServerDate(Date localDate, TimeZone localZone) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.setTime(localDate);
		
		int amount = TimeZone.getDefault().getRawOffset() - localZone.getRawOffset();
		calendar.add(Calendar.MILLISECOND, amount);
		
		return calendar.getTime();
	}
	
	/**
	 * 日期转换成字符串,采用当前登录的语言
	 * 
	 * @param date
	 * @return 日期
	 */
	public static String formateToLocaleDatetime(Date date){
		String datePattern = ResourceBundleUtil.getString("com.seeyon.v3x.common.resources.i18n.SeeyonCommonResources", "common.datetime.pattern");
		return format(date, datePattern, CurrentUser.get().getLocale());
	}

	/**
	 * 日期转换成字符串,采用当前登录的语言
	 * 
	 * @param date
	 * @return 日期 + 时间
	 */
	public static String formateToLocaleDate(Date date){
		String datePattern = ResourceBundleUtil.getString("com.seeyon.v3x.common.resources.i18n.SeeyonCommonResources", "common.date.pattern");
		return format(date, datePattern, CurrentUser.get().getLocale());
	}

	/**
	 * 计算日期间隔的天数
	 * @param theDay  时间1
	 * @param otherDay  时间2
	 * @return 间隔天数,theDay应该大于otherDay
	 */
	public static long minusDay(Date theDay,Date otherDay) {
		long minusDay = theDay.getTime() - otherDay.getTime();
		return minusDay/(1000*60*60*24);
	}
	
	/**
	 * 计算日期详细时间间隔
	 * @author jincm 2008-6-10
	 * @param theDay  时间1
	 * @param otherDay  时间2
	 * @return long[]{天数,小时数,分钟数,秒数}
	 */
	public static long[] detailInterval(Date theDay, Date otherDay){
		if(otherDay == null)
			return null;
		
		long seconds = (otherDay.getTime() - theDay.getTime())/1000;  
		long date = seconds/(24*60*60);//相差的天数  
		long hour = (seconds-date*24*60*60)/(60*60);//相差的小时数 
		long minut = (seconds-date*24*60*60-hour*60*60)/(60);//相差的分钟数  
		long second = (seconds-date*24*60*60-hour*60*60-minut*60);//相差的秒数  
		
		return new long[]{date,hour,minut,second};
	}
	
	/**
	 * long型数据转换
	 * @author jincm 2008-6-10
	 * @param long 分钟数
	 * @return long[]{天数,小时数,分钟数,秒数}
	 */
	public static long[] formatLongToTimeStr(long millisecond){
	    long seconds = millisecond/1000;  
	    long date = seconds/(24*60*60);//相差的天数  
		long hour = (seconds-date*24*60*60)/(60*60);//相差的小时数 
		long minut = (seconds-date*24*60*60-hour*60*60)/(60);//相差的分钟数  
		long second = (seconds-date*24*60*60-hour*60*60-minut*60);//相差的秒数
		return new long[]{date,hour,minut,second};
	}
	
	/**
	 * 将分钟数转换成XX小时XX分
	 * @param times
	 * @return
	 */
	public static String formatMins2TimeStr(Integer times){
		if(times == null){
			return null;
		}
		int hours = times/60;
		int mins = times - (60*hours);
		return ResourceBundleUtil.getString("com.seeyon.v3x.common.resources.i18n.SeeyonCommonResources", "common.date.times", hours, mins);
	}

}

你可能感兴趣的:(工具类,日期)