package com.base.core.utiles;

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

/**
 * Time Utility provides the following functions:
 * <br>
 * <b><i>1.</i></b> inFormat: to see does the time has FORMAT presented by format
 * <br>
 * <b><i>2.</i></b> parseTime: parse time from {@link String} to {@link Calendar} with given format, if the format is not given the {@linkplain defaultFormat} will be used
 * <br>
 * <b><i>3.</i></b> try2ParseTime: try to parse time from {@link String} to {@link Calendar} without given format, in this method three formats will be tried, they are {@linkplain shortFormat}, {@linkplain defaultFormat} and {@linkplain longFormat}
 * <br>
 * <b><i>4.</i></b> parseTime2: parse time from {@link String} to {@link Date} with given format, if the format is not given the {@linkplain defaultFormat} will be used
 * <br>
 * <b><i>5.</i></b> toString: parse time from {@link Calendar} to {@link String} with given format, if the format is not given the {@linkplain defaultFormat} will be used
 * <br>
 * <b><i>6.</i></b> diff: calculate the period between time1(instance of {@link String}) and time2(instance of {@link String}) with FORMAT presented by format in millisecond
 * <br>
 * <b><i>7.</i></b> diff: calculate the period between time1(instance of {@link Timestamp}) and time2(instance of {@link Timestamp}) with FORMAT presented by format in millisecond
 * <br>
 * <b><i>8.</i></b> getCurTime: get the current time(instance of {@link String}) with FORMAT presented by format
 * <br>
 * 
 * 
 * @version
 * 			v0.0.1
 * @author 
 * 			D.H. Sue @ 2016-07-07
 *
 */
public class TimeUtils {
	public static Calendar getCalendar(int year, int month, int day, int hour, int minute, int second) {
		String timeStr = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
		return parseTime(timeStr, defaultFormat);
	}
	public static Calendar getCalendar(int year, int month, int day, int hour, int minute, int second, int millisecond) {
		String timeStr = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second+"."+millisecond;
		return parseTime(timeStr, defaultFormat);
	}
	/**
	 * Format as yyyy-MM-dd
	 */
	public static final String shortFormat = "yyyy-MM-dd";
	
	/**
	 * Format as yyyy-MM-dd
	 */
	public static final String batchFormat = "yyyyMMdd";
	
	/**
	 * Format as yyyy-MM-dd HH:mm:ss
	 */
	public static final String defaultFormat = "yyyy-MM-dd HH:mm:ss";
	
	/**
	 * Format as yyyy-MM-dd HH:mm:ss.SSS
	 */
	public static final String longFormat = "yyyy-MM-dd HH:mm:ss.SSS";

	
	public static String longFormatStrToDefaultFormat(String date)
	{
		SimpleDateFormat sdf = new SimpleDateFormat(longFormat);
		sdf.setLenient(false);
		Date newDate = null;
		try {
			newDate = sdf.parse(date);
		} catch (ParseException e) {			
			e.printStackTrace();
		}
		sdf=new SimpleDateFormat(defaultFormat);
		return sdf.format(newDate);
	}
	/**
	 * To see does the time have the FORMAT presented by format
	 * 
	 * @param time
	 * 			time that will be checked
	 * @param format
	 * 			the given format
	 * @return
	 * 			boolean, true means the time is in FORMAT presented by format, false means not
	 */
	public static boolean inFormat(String time, String format) {
		if (StringUtils.isNoE(format)) {
			return false;
		}
		if (StringUtils.isNoE(time)) {
			return false;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			Calendar.getInstance().setTime(sdf.parse(time));
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	/**
	 * Parse time 2 {@link Calendar}, if time is not specified, the current {@link Calendar} will be returned
	 * 
	 * @param time
	 * 			time, which is a {@link String}
	 * @param format
	 * 			time's format, if not specified, defaultFormat[yyyy-MM-dd hh:mm:ss] will be used
	 * @return
	 * 			{@link Calendar}
	 */
//	public static Calendar parseTime(String time, String format) {
//		Calendar cal = Calendar.getInstance();
//		if (!StringUtils.isNoE(time)) {
//			format = StringUtils.isNoE(format) ? defaultFormat : format;
//			SimpleDateFormat sdf = new SimpleDateFormat(format);
//			try {
//				cal.setTime(sdf.parse(time));
//			} catch (ParseException e) {
//				e.printStackTrace();
//			}
//		}
//		return cal;
//	}
	
	public static Calendar parseTime(String time, String format) {
		Calendar cal = Calendar.getInstance();
		if (!StringUtils.isNoE(time)) {
			SimpleDateFormat sdf = new SimpleDateFormat(longFormat);
			try {
				cal.setTime(sdf.parse(time));
			} catch (Exception e) {
				try {
					sdf = new SimpleDateFormat(defaultFormat);
					cal.setTime(sdf.parse(time));
				} catch (Exception e2) {
					try {
						sdf = new SimpleDateFormat(shortFormat);
						cal.setTime(sdf.parse(time));
					} catch (Exception e3) {
						e3.printStackTrace();
					}
					return cal;
				}
				return cal;
			}
		}
		return cal;
	}
	
	/** 
	 * Try 2 parse a time with 3 different format
	 * 
	 * @param time
	 * 			{@link String}: time that will be parsed
	 * @return
	 * 			{@link Calendar} if time parsed correctly, null if some Exception occurs
	 */
	public static Calendar try2ParseTime(String time) {
		Calendar cal = Calendar.getInstance();
		if (!StringUtils.isNoE(time)) {
			SimpleDateFormat sdf = new SimpleDateFormat(longFormat);
			try {
				cal.setTime(sdf.parse(time));
			} catch (Exception e) {
				try {
					sdf = new SimpleDateFormat(defaultFormat);
					cal.setTime(sdf.parse(time));
				} catch (Exception e2) {
					try {
						sdf = new SimpleDateFormat(shortFormat);
						cal.setTime(sdf.parse(time));
					} catch (Exception e3) {
						try {
							sdf = new SimpleDateFormat(batchFormat);
							cal.setTime(sdf.parse(time));
						} catch (Exception e4) {
							e4.printStackTrace();
						}
						return cal;
					}
					return cal;
				}
				return cal;
			}
		}
		return cal;
	}
	
	/**
	 * Convert a {@link Date} into {@link String} in format
	 * 
	 * @param cal
	 * 			{@link Date}
	 * @param format
	 * 			format, if not assigned, a default format(yyyy-mm-dd HH:mm:ss) will be used
	 * @return
	 * 			{@link String} in format
	 */
	public static String dateToString(Date date, String format) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		String str = "";
		format = StringUtils.isNoE(format) ? defaultFormat : format;
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			str = sdf.format(cal.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}
	
	/**
	 * Parse time 2 {@link Date}
	 * 
	 * @param time
	 * 			time, which is a {@link String}
	 * @param format
	 * 			time's format, if not specified, defaultFormat[yyyy-MM-dd hh:mm:ss] will be used
	 * @return
	 * 			{@link Date}
	 */
	public static Date parseTime2(String time, String format) {
		Date date = new Date();
		if (!StringUtils.isNoE(time)) {
			format = StringUtils.isNoE(format) ? defaultFormat : format;
			SimpleDateFormat sdf = new SimpleDateFormat(format);
			try {
				date = sdf.parse(time);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}
		return date;
	}
	
	/**
	 * Convert a {@link Calendar} into {@link String} in format
	 * 
	 * @param cal
	 * 			{@link Calendar}
	 * @param format
	 * 			format, if not assigned, a default format(yyyy-mm-dd HH:mm:ss) will be used
	 * @return
	 * 			{@link String} in format
	 */
	public static String toString(Calendar cal, String format) {
		String str = "";
		format = StringUtils.isNoE(format) ? defaultFormat : format;
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			str = sdf.format(cal.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}
	
	public static void main(String[] args) {
		String time = "";
		Calendar cal = try2ParseTime(time);
		System.out.println(cal);
	}

	/**
	 * Return time difference between [startTime, endTime] in millisecond
	 * 
	 * @param startTime
	 * 			startTime
	 * @param endTime
	 * 			endTime
	 * @return
	 * 			Time difference in millisecond
	 */
	public static long diff(String startTime, String endTime, String format) {
		Calendar startCal = try2ParseTime(startTime);
		Calendar endCal = try2ParseTime(endTime);
//		Calendar startCal = parseTime(startTime, format);
//		Calendar endCal = parseTime(endTime, format);
		return (endCal.getTimeInMillis() - startCal.getTimeInMillis());
	}

	/**
	 * Return time difference between [startTime, endTime] in millisecond
	 * 
	 * @param startTime
	 * 			startTime
	 * @param endTime
	 * 			endTime
	 * @return
	 * 			Time difference in millisecond
	 */
	public static long diff(Timestamp startTime, Timestamp endTime) {
		return startTime.getTime() - endTime.getTime();
	}

	/**
	 * Return current time in specified format
	 * 
	 * @param format
	 * 			specified format
	 * @return
	 * 			{@link String}: current time
	 */
	public static String getCurTime(String format) {
		Calendar cal = Calendar.getInstance();
		String str = toString(cal, format);
		return str;
	}

	/**
	 * 取两个时间的中间时刻
	 * 
	 * @param startTime
	 * 			开始时间
	 * @param endTime
	 * 			结束时间
	 * @return
	 * 			中间时间
	 */
	public static String centerTime(String startTime, String endTime) {
		Calendar startCal = parseTime(startTime, longFormat);
		Calendar endCal = parseTime(endTime, longFormat);
		long span = endCal.getTimeInMillis() - startCal.getTimeInMillis();
		Calendar centerCal = Calendar.getInstance();
		centerCal.setTime(startCal.getTime());
		centerCal.add(Calendar.MILLISECOND, (int) (span / 2));
		return toString(centerCal, longFormat);
	}

	public static String toString(Date date, String format) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		String str = "";
		format = StringUtils.isNoE(format) ? defaultFormat : format;
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			str = sdf.format(cal.getTime());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}
}
