package cn.edu.tju.se.base.service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import cn.edu.tju.se.base.common.CommonConstants;

public class DateService {
	
	public static final 	SimpleDateFormat DateFormat = new SimpleDateFormat(
			"yyyy-MM-dd");

	public static final 	SimpleDateFormat TimeFormat = new SimpleDateFormat(
			"HH:mm:ss");

	public static final 	SimpleDateFormat DatetimeFormat = new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss");
	
	public static Integer getAbsoluteMiniteInAday(Integer hour,Integer minite){
		return hour*CommonConstants.MINITES_PER_HOUR+minite;
	}
	
	public static Integer getHourFromAbsoluteMinite(Integer absoluteMinite){
		return absoluteMinite/CommonConstants.MINITES_PER_HOUR;
	}
	
	public static Integer getMiniteFromAbsoluteMinite(Integer absoluteMinite){
		return absoluteMinite%CommonConstants.MINITES_PER_HOUR;
	}

	public static Integer getWeekday(Date date) {
		// 将 Date 对象反应到一个 Calendar 对象中，
		// Calendar/GregorianCalendar 没有构造函数可以接受 Date 对象
		// 所以我们必需先获得一个实例，然后设置 Date 对象
		Calendar calendar = Calendar.getInstance();		
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK)-1;
	}
	
	public static Integer getAbsoluteMinite(Date date){
		// 将 Date 对象反应到一个 Calendar 对象中，
		// Calendar/GregorianCalendar 没有构造函数可以接受 Date 对象
		// 所以我们必需先获得一个实例，然后设置 Date 对象
		Calendar calendar = Calendar.getInstance();		
		calendar.setTime(date);
		Integer hour =  calendar.get(Calendar.HOUR_OF_DAY);
		Integer minite = calendar.get(Calendar.MINUTE);
		return hour * CommonConstants.MINITES_PER_HOUR + minite;
	}
	
	public static Date getStartOfDay(Date date){
		Calendar calendar = Calendar.getInstance();		
		calendar.setTime(date);
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH);
		int dayOfMonth = calendar.get(Calendar.DATE);
		Calendar calendar1 = Calendar.getInstance();
		calendar1.set(year, month, dayOfMonth, 0, 0, 0);
		calendar1.clear(Calendar.MILLISECOND);
		return calendar1.getTime();
	}
	
	public static Date getStartOfNextDay(Date date){
		Calendar calendar = Calendar.getInstance();		
		calendar.setTime(date);
		int year = calendar.get(Calendar.YEAR);
		int month = calendar.get(Calendar.MONTH);
		int dayOfMonth = calendar.get(Calendar.DATE);
		Calendar calendar1 = Calendar.getInstance();
		calendar1.set(year, month, dayOfMonth, 23, 59, 59);
		calendar1.clear(Calendar.MILLISECOND);
		calendar1.add(Calendar.SECOND, 1);
		return calendar1.getTime();
	}
	
	public static Date getEndOfDayOnMilliSecond(Date date){
		Date date1 = getStartOfNextDay(date);
		Calendar calendar1 = Calendar.getInstance();		
		calendar1.setTime(date1);
		calendar1.add(Calendar.MILLISECOND, -1);
		return calendar1.getTime();
	}
	
	public static Date stringToDate(String str, SimpleDateFormat format) {
		Date date = null;
		if (str==null||str.equals("")){
			return null;
		}
		try {
			date = format.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	public static String date2String(Date date,SimpleDateFormat format){
		String str = format.format(date);
		return str;
	}
	
	public static String getNow(){
		Calendar now = Calendar.getInstance();
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String str = fmt.format(now.getTime());
		return str;
	}
	public static String getToday(){
		Calendar now = Calendar.getInstance();
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
		String str = fmt.format(now.getTime());
		return str;
	}

	public enum OverlayType {
		BEFORE_APART, BEFORE_PARTIAL, BEFORE_FULL, EVEN_LT, MATCH, EVEN_GT, AFTER_FULL, AFTER_PARTIAL, AFTER_APART;
	}
	
	/**
	 * 比较AB两段时间的覆盖关系
	 * 时间段为前闭后开区间，即满足 start <= time < end的时间为时间段内
	 * 参数点要求为线性点，可以是绝对秒数（从1970年1月1日0时起）
	 * 也可以是一天内的绝对分钟数（相对0点0分的分钟数）（AB在同一天）
	 * 
	 * @param aStart：时间段A的线性起始点
	 * @param aEnd：时间段A在一天中的终止点
	 * @param bStart：时间段B在一天中的起始点
	 * @param bEnd：时间段B在一天中的终止点
	 * @return OverlayType ，代表A对B的关系。
	 */
	public static OverlayType checkOverlay(int aStart, int aEnd, int bStart, int bEnd) {
		OverlayType overlayType = null;
		if (aStart < bStart) { // BEFORE
			if (aEnd < bStart) {
				overlayType = OverlayType.BEFORE_APART;
			} else if (aEnd < bEnd) {
				overlayType = OverlayType.BEFORE_PARTIAL;
			} else {
				overlayType = OverlayType.BEFORE_FULL;
			}
		} else if (aStart == bStart) { // EVEN
			if (aEnd < bEnd) {
				overlayType = OverlayType.EVEN_LT;
			} else if (aEnd == bEnd) {
				overlayType = OverlayType.MATCH;
			} else {
				overlayType = OverlayType.EVEN_GT;
			}
		} else if (aStart > bStart) { // AFTER
			if (aEnd <= bEnd) {
				overlayType = OverlayType.AFTER_FULL;
			} else if (aStart <= bEnd) {
				overlayType = OverlayType.AFTER_PARTIAL;
			} else {
				overlayType = OverlayType.AFTER_APART;
			}
		}
		return overlayType;
	}
	
	public static Date addDays(Date date, Integer add){
		Calendar c  = Calendar.getInstance();	
		c.setTime(date);
		c.add(Calendar.DATE, add);
		return DateService.getStartOfDay(c.getTime());		
	}
}
