package com.dcit.common.utils;

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

/**
 * <p>
 * Title: DateUtil
 * </p>
 * <p>
 * Description: 日期转换工具
 * </p>
 * <p>
 * Company: SJZ DC-IT co. LTD
 * </p>
 * 
 * @author ZZZ
 * @date 2018年8月29日 下午5:13:53
 */
public class DateUtil {
	public static final String C_DATE_DIVISION = "-";

	public static final String C_TIME_PATTON_DEFAULT = "yyyy-MM-dd HH:mm:ss";
	public static final String C_DATE_PATTON_DEFAULT = "yyyy-MM-dd";
	public static final String C_DATA_PATTON_YYYYMMDD = "yyyyMMdd";
	public static final String C_DATA_PATTON_YYYYMM = "yyyyMM";
	public static final String C_DATA_PATTON_DD = "yyyyMMdd";
	public static final String C_TIME_PATTON_HHMMSS = "HH:mm:ss";
	public static final String C_YEAR_PATTON = "yyyy";

	public static final String C_TIME_PATTON_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	public static final int C_ONE_SECOND = 1000;
	public static final int C_ONE_MINUTE = 60 * C_ONE_SECOND;
	public static final int C_ONE_HOUR = 60 * C_ONE_MINUTE;
	public static final long C_ONE_DAY = 24 * C_ONE_HOUR;

	/**
	 * Return the current date
	 * 
	 * @return － DATE<br>
	 */
	public static Date getCurrentDate() {
		Calendar cal = Calendar.getInstance();
		Date currDate = cal.getTime();

		return currDate;
	}

	/**
	 * Return the current date string
	 * 
	 * @return － 产生的日期字符串<br>
	 */
	public static String getCurrentDateStr() {
		Calendar cal = Calendar.getInstance();
		Date currDate = cal.getTime();

		return format(currDate);
	}

	/**
	 * Return the current date in the specified format
	 * 
	 * @param strFormat
	 * @return
	 */
	public static String getCurrentDateStr(String strFormat) {
		Calendar cal = Calendar.getInstance();
		Date currDate = cal.getTime();

		return format(currDate, strFormat);
	}

	/**
	 * Parse a string and return a date value
	 * 
	 * @param dateValue
	 * @return
	 * @throws Exception
	 */
	public static Date parseDate(String dateValue) {
		return parseDate(C_DATE_PATTON_DEFAULT, dateValue);
	}

	/**
	 * Parse a strign and return a datetime value
	 * 
	 * @param dateValue
	 * @return
	 */
	public static Date parseDateTime(String dateValue) {
		return parseDate(C_TIME_PATTON_DEFAULT, dateValue);
	}

	/**
	 * Parse a string and return the date value in the specified format
	 * 
	 * @param strFormat
	 * @param dateValue
	 * @return
	 * @throws ParseException
	 * @throws Exception
	 */
	public static Date parseDate(String strFormat, String dateValue) {
		if (dateValue == null)
			return null;

		if (strFormat == null)
			strFormat = C_TIME_PATTON_DEFAULT;

		SimpleDateFormat dateFormat = new SimpleDateFormat(strFormat);
		Date newDate = null;

		try {
			newDate = dateFormat.parse(dateValue);
		} catch (ParseException pe) {
			pe.printStackTrace();
			newDate = null;
		}

		return newDate;
	}

	/**
	 * 将Timestamp类型的日期转换为系统参数定义的格式的字符串。
	 * 
	 * @param aTs_Datetime
	 *            需要转换的日期。
	 * @return 转换后符合给定格式的日期字符串
	 */
	public static String format(Date aTs_Datetime) {
		return format(aTs_Datetime, C_DATE_PATTON_DEFAULT);
	}

	/**
	 * 将Timestamp类型的日期转换为系统参数定义的格式的字符串。
	 * 
	 * @param aTs_Datetime
	 *            需要转换的日期。
	 * @return 转换后符合给定格式的日期字符串
	 */
	public static String formatTime(Date aTs_Datetime) {
		return format(aTs_Datetime, C_TIME_PATTON_DEFAULT);
	}

	/**
	 * 金蝶K3系统需要的时间戳
	 * 
	 * @param aTs_Datetime
	 * @return
	 */
	public static String formatYYYYMMDDHHMMSS(Date aTs_Datetime) {
		return format(aTs_Datetime, C_TIME_PATTON_YYYYMMDDHHMMSS);
	}

	/**
	 * 将Date类型的日期转换为系统参数定义的格式的字符串。
	 * 
	 * @param aTs_Datetime
	 * @param as_Pattern
	 * @return
	 */
	public static String format(Date aTs_Datetime, String as_Pattern) {
		if (aTs_Datetime == null || as_Pattern == null)
			return null;

		SimpleDateFormat dateFromat = new SimpleDateFormat();
		dateFromat.applyPattern(as_Pattern);

		return dateFromat.format(aTs_Datetime);
	}

	/**
	 * @param aTs_Datetime
	 * @param as_Format
	 * @return
	 */
	public static String formatTime(Date aTs_Datetime, String as_Format) {
		if (aTs_Datetime == null || as_Format == null)
			return null;

		SimpleDateFormat dateFromat = new SimpleDateFormat();
		dateFromat.applyPattern(as_Format);

		return dateFromat.format(aTs_Datetime);
	}

	public static String getFormatTime(Date dateTime) {
		return formatTime(dateTime, C_TIME_PATTON_HHMMSS);
	}

	/**
	 * @param aTs_Datetime
	 * @param as_Pattern
	 * @return
	 */
	public static String format(Timestamp aTs_Datetime, String as_Pattern) {
		if (aTs_Datetime == null || as_Pattern == null)
			return null;

		SimpleDateFormat dateFromat = new SimpleDateFormat();
		dateFromat.applyPattern(as_Pattern);

		return dateFromat.format(aTs_Datetime);
	}

	/**
	 * 取得指定日期N天后的日期
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static Date addDays(Date date, int days) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		cal.add(Calendar.DAY_OF_MONTH, days);

		return cal.getTime();
	}

	/**
	 * 取得指定日期N月后的日期
	 * 
	 * @param date
	 * @param month
	 * @return
	 */
	public static Date addMonth(Date date, int month) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);

		cal.add(Calendar.MONTH, month);

		return cal.getTime();
	}

	/**
	 * 计算两个日期之间相差的天数
	 * 
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int daysBetween(Date date1, Date date2) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date1);
		long time1 = cal.getTimeInMillis();
		cal.setTime(date2);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);

		return Integer.parseInt(String.valueOf(between_days));
	}

	/**
	 * 计算当前日期相对于"1977-12-01"的天数
	 * 
	 * @param date
	 * @return
	 */
	public static long getRelativeDays(Date date) {
		Date relativeDate = DateUtil.parseDate("yyyy-MM-dd", "1977-12-01");

		return DateUtil.daysBetween(relativeDate, date);
	}

	public static Date getDateBeforTwelveMonth() {
		String date = "";
		Calendar cla = Calendar.getInstance();
		cla.setTime(getCurrentDate());
		int year = cla.get(Calendar.YEAR) - 1;
		int month = cla.get(Calendar.MONTH) + 1;
		if (month > 9) {
			date = String.valueOf(year) + C_DATE_DIVISION + String.valueOf(month) + C_DATE_DIVISION + "01";
		} else {
			date = String.valueOf(year) + C_DATE_DIVISION + "0" + String.valueOf(month) + C_DATE_DIVISION + "01";
		}

		Date dateBefore = parseDate(date);
		return dateBefore;
	}

	/**
	 * 传入时间字符串,加一天后返回Date
	 * 
	 * @param date
	 *            时间 格式 YYYY-MM-DD
	 * @return
	 */
	public static Date addDate(String date) {
		if (date == null) {
			return null;
		}

		Date tempDate = parseDate(C_DATE_PATTON_DEFAULT, date);
		String year = format(tempDate, "yyyy");
		String month = format(tempDate, "MM");
		String day = format(tempDate, "dd");

		GregorianCalendar calendar = new GregorianCalendar(Integer.parseInt(year), Integer.parseInt(month) - 1,
				Integer.parseInt(day));

		calendar.add(Calendar.DATE, 1);
		return calendar.getTime();
	}

	/***
	 * 取得起止日期间的天数集合
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static List<String> listStartToEndDate(String startDate, String endDate, String dateFormat) {
		SimpleDateFormat format = new SimpleDateFormat(dateFormat);
		List<String> al = new ArrayList<String>();
		if (startDate.equals(endDate)) {
			// IF起始日期等于截止日期,仅返回起始日期一天
			al.add(startDate);
		} else if (startDate.compareTo(endDate) <= 0) {
			// IF起始日期早于截止日期,返回起止日期的每一天
			while (startDate.compareTo(endDate) <= 0) {
				al.add(startDate);
				try {
					Long l = format.parse(startDate).getTime();
					startDate = format.format(l + 3600 * 24 * 1000);// +1天
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} else {
			// IF起始日期晚于截止日期,仅返回起始日期一天
			al.add(startDate);
		}
		return al;
	}

	/**
	 * 当前时间是星期几
	 *
	 * @return
	 */
	public static int getWeekDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int week_of_year = c.get(Calendar.DAY_OF_WEEK);
		return week_of_year - 1;
	}
	
	/**
	   * 获取当前日期是星期几<br>
	   * 
	   * @param dt
	   * @return 当前日期是星期几
	   */
	public static String getWeekOfDateStr(Date dt) {
		//int[] weekDays = {7, 1, 2, 3, 4, 5, 6};
		String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
		Calendar cal = Calendar.getInstance();
		cal.setTime(dt);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		if (w < 0)
		    w = 0;
		return weekDays[w];
   }
	
	/**
	 * 获取当前日期是今年第几周
	 * @param dt
	 * @return
	 */
	public static String getWeekOfYear(String dt){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
		Date date = null;  
		try {  
		    date = format.parse(dt);  
		} catch (ParseException e) {  
		    // TODO Auto-generated catch block  
		    e.printStackTrace();  
		}  
		  
		Calendar calendar = Calendar.getInstance();  
		calendar.setFirstDayOfWeek(Calendar.MONDAY);  
		calendar.setTime(date);  
		
		int week = calendar.get(Calendar.WEEK_OF_YEAR);
		String weekStr = ""+week;
		if(week<9){
			weekStr = "0"+week;
		}
		
		return weekStr;
	}
	
	/**
	 * 获取当前日期是今年第几周的前一周
	 * @param dt
	 * @return
	 */
	public static String getLastWeekOfYear(String dt){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
		Date date = null;  
		try {  
		    date = format.parse(dt);  
		} catch (ParseException e) {  
		    // TODO Auto-generated catch block  
		    e.printStackTrace();  
		}  
		  
		Calendar calendar = Calendar.getInstance();  
		calendar.setFirstDayOfWeek(Calendar.MONDAY);  
		calendar.setTime(date);  
		
		int week = calendar.get(Calendar.WEEK_OF_YEAR)-1;
		String weekStr = ""+week;
		if(week<9){
			weekStr = "0"+week;
		}
		
		return weekStr;
	}

	/**
	 * 获得本周的第一天，周一
	 *
	 * @return
	 */
	public static Date getWeekStartTime(Date date) {
		/*Calendar c = Calendar.getInstance();
		c.setTime(date);
		try {
		//如果当前时间是星期天，则向上移动一天，再取本周的星期一，老外用周日到周六为一周，向前移动一天，则是中国人的本周
			int weekday = c.get(Calendar.DAY_OF_WEEK)-2;
			System.out.println(weekday + "");
			c.add(Calendar.DATE, -weekday);
			c.setTime(longSdf.parse(shortSdf.format(c.getTime()) + " 00:00:00.000"));
		} catch (Exception e) {
			e.printStackTrace();
		}*/
		
		Calendar cal=new GregorianCalendar();
		try {
			cal.setFirstDayOfWeek(Calendar.MONDAY);
			cal.setTime(date);
			cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		String dataStr = DateUtil.format(cal.getTime(), DateUtil.C_DATE_PATTON_DEFAULT);
		
		return DateUtil.parseDate(DateUtil.C_TIME_PATTON_DEFAULT, dataStr+" 00:00:00");
	}

	/**
	 * 获得本周的最后一天，周日
	 *
	 * @return
	 */
	public static Date getWeekEndTime(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		try {
			/*int weekday = c.get(Calendar.DAY_OF_WEEK);
			c.add(Calendar.DATE, 8 - weekday);
			c.setTime(longSdf.parse(shortSdf.format(c.getTime()) + " 23:59:59.999"));*/
			cal.setFirstDayOfWeek(Calendar.MONDAY);
	        cal.set(Calendar.DAY_OF_WEEK, cal.getFirstDayOfWeek() + 6);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		String dataStr = DateUtil.format(cal.getTime(), DateUtil.C_DATE_PATTON_DEFAULT);
		
		return DateUtil.parseDate(DateUtil.C_TIME_PATTON_DEFAULT, dataStr+" 23:59:59");
	}

	/**
	 * 时间段内的周数
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static Object countTwoDayWeek(Date startDate, Date endDate) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(startDate);
		long time1 = cal.getTimeInMillis();
		cal.setTime(endDate);
		long time2 = cal.getTimeInMillis();
		long between_days = (time2 - time1) / (1000 * 3600 * 24);
		Double days = Double.parseDouble(String.valueOf(between_days));
		if ((days / 7) > 0 && (days / 7) <= 1) {
			// 不满一周的按一周算
			return 1;
		} else if (days / 7 > 1) {
			int day = days.intValue();
			if (day % 7 > 0) {
				return day / 7 + 1;
			} else {
				return day / 7;
			}
		} else if ((days / 7) == 0) {
			return 0;
		} else {
			// 负数返还null
			return null;
		}
	}

	/**
	 * 看两个日期是否有交集 A时间段,B时间段 时间格式:yyyy-MM-dd
	 */
	public static boolean compareDate(String startA, String endA, String startB, String endB) throws Exception {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date a1 = sdf.parse(startA);
		Date a2 = sdf.parse(endA);

		Date b1 = sdf.parse(startB);
		Date b2 = sdf.parse(endB);

		/**
		 * if(第一组最后时间小于等于第二组最前时间 || 第一组最前时间大于等于第二组最后时间){ 无交集 } else { 有交集 }
		 */
		if ((a2.getTime() <= b1.getTime()) || a1.getTime() >= b2.getTime()) {
			return false;
		} else {
			return true;
		}
	}

	/**
	* 获取当月第一天
	* @return
	*/
	public static String getMonthFirstday(){
		SimpleDateFormat formater=new SimpleDateFormat("MM/dd/yyyy");
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, 0);
		c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 
		String first = formater.format(c.getTime());
		return first;
	}
	
	public static void main(String[] args){
		
		System.out.println(getCurrentDateStr(C_YEAR_PATTON));
		System.out.println(DateUtil.getCurrentDateStr(DateUtil.C_YEAR_PATTON)+ DateUtil.getWeekOfYear("2020-05-03"));
	}
	

}