/**
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.sifang.modules.sys.common.utils;


import cn.hutool.core.date.DateUnit;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期工具类, 继承org.apache.commons.lang.time.DateUtils类
 * @version 2019-11-15
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
	
	private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", 
		"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" };

	/**
	 * 获取当前Date型日期
	 *
	 * @return Date() 当前日期
	 */
	public static Date getNowDate() {
		return new Date();
	}

	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd）
	 */
	public static String getDate() {
		return getDate("yyyy-MM-dd");
	}
	
	/**
	 * 得到当前日期字符串 格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String getDate(String pattern) {
		return DateFormatUtils.format(new Date(), pattern);
	}
	
	/**
	 * 得到日期字符串 默认格式（yyyy-MM-dd） pattern可以为："yyyy-MM-dd" "HH:mm:ss" "E"
	 */
	public static String formatDate(Date date, Object... pattern) {
		String formatDate = null;
		if (pattern != null && pattern.length > 0) {
			formatDate = DateFormatUtils.format(date, pattern[0].toString());
		} else {
			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
		}
		return formatDate;
	}

	public static String dayStr(Date date) {
		return formatYMDDateTime(date);
	}
	
	/**
	 * 得到日期时间字符串，转换格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String formatDateTime(Date date) {
		if(date != null)
			return formatDate(date, "yyyy-MM-dd HH:mm:ss");
		else
			return "";
	}

	public static String formatYMDDateTime(Date date)
	{
		if(date != null)
			return formatDate(date,"yyyy-MM-dd");
		else
			return "";
	}
	/**
	 * 得到当前时间字符串 格式（HH:mm:ss）
	 */
	public static String getTime() {
		return formatDate(new Date(), "HH:mm:ss");
	}

	/**
	 * 得到当前日期和时间字符串 格式（yyyy-MM-dd HH:mm:ss）
	 */
	public static String getDateTime() {
		return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
	}

	/**
	 * 得到当前年份字符串 格式（yyyy）
	 */
	public static String getYear() {
		return formatDate(new Date(), "yyyy");
	}

	/**
	 * 得到当前月份字符串 格式（MM）
	 */
	public static String getMonth() {
		return formatDate(new Date(), "MM");
	}

	/**
	 * 得到当天字符串 格式（dd）
	 */
	public static String getDay() {
		return formatDate(new Date(), "dd");
	}

	/**
	 * 得到当前星期字符串 格式（E）星期几
	 */
	public static String getWeek() {
		return formatDate(new Date(), "E");
	}
	
	/**
	 * 日期型字符串转化为日期 格式
	 * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", 
	 *   "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" }
	 */
	public static Date parseDate(Object str) {
		if (str == null){
			return null;
		}
		try {
			return parseDate(str.toString(), parsePatterns);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * 获取过去的天数
	 * @param date
	 * @return
	 */
	public static long pastDays(Date date) {
		long t = new Date().getTime()-date.getTime();
		return t/(24*60*60*1000);
	}

	/**
	 *
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static String  pastHour(Date date1,Date date2) {
		long hour= 0;
		long day = 0;
		String phour = "0";
		long nd = 1000 * 24 * 60 * 60;
		long nh = 1000 * 60 * 60;
		long nm = 1000 * 60;
		try
		{
			long diff = date1.getTime() - date2.getTime();
			day = diff / nd; //天数
			 hour = diff % nd / nh;
			long min = diff % nd % nh / nm;
			float price = (day*24) +(float)hour+((float) min/60f);
			DecimalFormat decimalFormat=new DecimalFormat("0.00");//构造方法的字符格式这里如果小数不足2位,会以0补足.
			phour=decimalFormat.format(price);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return phour;
	}


	/**
	 * 两个时间相差距离多少天多少小时多少分多少秒
	 * @param str1 时间参数 1 格式：2016-06-22 18:21:20
	 * @param str2 时间参数 2 格式：2016-06-22 17:21:20
	 * @param )
	 * @return String 返回值为：xx天xx小时xx分xx秒
	 */
	public static String getDistanceTime(Date str1, Date str2) {
	//	DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long day = 0;
		long hour = 0;
		long min = 0;
		long sec = 0;
		long ms = 0;
		try {
			long time1 = str1.getTime();
			long time2 = str2.getTime();
			long diff ;
			if(time1 < time2) {
				diff = time2 - time1;
			} else {
				diff = time1 - time2;
			}
			day = diff / (24 * 60 * 60 * 1000);
			hour = (diff / (60 * 60 * 1000) - day * 24);
			min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
			sec = (diff/1000-day*24*60*60-hour*60*60-min*60);
			//ms = (diff - day * 24 * 60 * 60 * 1000 - hour * 60 * 60 * 1000 - min * 60 * 1000 - sec * 1000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return day + "天" + hour + "小时" + min + "分" + sec + "秒";
		//return day + "天" + hour + "小时" + min + "分" + sec + "秒" + ms + "毫秒";
	}


    
	public static Date getDateStart(Date date) {
		if(date==null) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			date= sdf.parse(formatDate(date, "yyyy-MM-dd")+" 00:00:00");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	public static Date getDateEnd(Date date) {
		if(date==null) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			date= sdf.parse(formatDate(date, "yyyy-MM-dd") +" 23:59:59");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;
	}
	
	/**
	 *转换Excel中的日期类型，统一返回的都是yyyy-MM-dd HH:mm:ss格式的字符串 
	 * @throws Exception 
	 */
	public static Date converExcelDate(String dateStr) throws Exception {
		String pattern = "[0-9]*";
		if(dateStr.matches(pattern)){//进入Excel的日期格式1900-01-01的区分格式
			
			Date originalDate = org.apache.commons.lang3.time.DateUtils.parseDate("1900-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
			long long1 = originalDate.getTime(); 
			long dateLong = long1 + ( (Long.valueOf(dateStr) - 2 ) * 24 * 60 * 60 * 1000 );
			System.out.println(new Date(dateLong));
			return new Date(dateLong);
		}else{//进入Excel的文本格式
			return org.apache.commons.lang3.time.DateUtils.parseDate(dateStr, "yyyy-MM-dd");
		}
	}
	
	/**
	 * @param args
	 * @throws ParseException
	 */
	public static void main(String[] args) throws ParseException {
		System.out.println(getTwoTimeBetMin("2024-03-10 13:10:20","2024-03-11 13:10:20"));

		//System.out.println(subMonth("2023-06-14 22:26:16",12));
	}

	// date必须是日期格式yyyy-MM-dd
	public static String nextDate(String date) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		try {
			Date d = df.parse(date);
			Calendar instance = Calendar.getInstance();
			instance.setTime(d);
			instance.add(Calendar.DATE, 1);
			return new SimpleDateFormat("yyyy-MM-dd").format(instance.getTime());
		} catch (ParseException e) {
			throw new RuntimeException(e);
		}
	}

	public static String subDate(Date date, int days){
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DATE, -days);
		return formatDate(calendar.getTime(), "yyyy-MM-dd");
	}

	/**
	 * 将日期加/减去指定天数
	 *
	 * @param targetTime
	 * @param dateLong   (负数减 正数加)
	 * @return
	 */
	public static String dateChangeDays(Date targetTime, int dateLong,String patten) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(targetTime);
		cal.add(Calendar.DATE, dateLong);
		return DateFormatUtils.format(cal.getTime(), patten);
	}

	/****
	 * 传入具体日期 ，返回具体日期增加N月。
	 * @param date 日期(2017-04-13)
	 * @return 2017-05-13
	 * @throws ParseException
	 */
	public static String subMonth(String date, int days) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date dt = sdf.parse(date);
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(dt);
		rightNow.add(Calendar.MONTH, days);
		Date dt1 = rightNow.getTime();
		String reStr = sdf.format(dt1);
		return reStr;
	}



	/**
	 * 计算两个日期之间相差的天数
	 * @param smdate 较小的时间
	 * @param bdate  较大的时间
	 * @return 相差天数
	 */
	public static long daysBetween(String smdate,String bdate) throws ParseException{
		SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
		Calendar cal = Calendar.getInstance();
		cal.setTime(sdf.parse(smdate));
		long time1 = cal.getTimeInMillis();
		cal.setTime(sdf.parse(bdate));
		long time2 = cal.getTimeInMillis();
		long between_days=(time2-time1)/(1000*3600*24);
		return between_days;
	}

	// 获取两个时间相差分钟数
	public static long getTwoTime(String oldTime,String newTime) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
			Calendar cal = Calendar.getInstance();
			cal.setTime(sdf.parse(oldTime));
			long time1 = cal.getTimeInMillis();
			cal.setTime(sdf.parse(newTime));
			long time2 = cal.getTimeInMillis();
			long between_days=(time2-time1)/(1000*60);
		/*	long ntime =sdf.parse(newTime).getTime();
			long otime =sdf.parse(oldTime).getTime();
			long diff = (ntime-otime)/1000/60;
			System.out.println(diff);*/
			return between_days;
		}catch (Exception e){
			e.printStackTrace();
		}
	return 80;
	}

	/**
	 *   根据两个日期获取相差年数
	 * @param startDate  日期起期
	 * @param endDate    日期止期
	 * @return
	 */
	public static int getYear(Date startDate, Date endDate) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
		String startDateStr = simpleDateFormat.format(startDate);
		String endDateStr = simpleDateFormat.format(endDate);
		return (Integer.parseInt(endDateStr) - Integer.parseInt(startDateStr)) / 10000;
	}




	public static boolean isNow(String date) {
		// 当前时间
		Date now = new Date();
		Date dates = parseDate(date);
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		//获取今天的日期
		String nowDay = sf.format(now);
		//对比的时间
		String day = sf.format(dates);

		return day.equals(nowDay);
	}

	public static Date yearSub(Date targetTime, int yearLong) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(targetTime);
		cal.add(Calendar.YEAR, yearLong);
		return cal.getTime();
	}

	/**
	 * 获取两个日期之间的所有月份 (年月)
	 *
	 * @param startTime
	 * @param endTime
	 * @return：list
	 */
	public static List<String> getMonthBetweenDate(String startTime, String endTime) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
		// 声明保存日期集合
		List<String> list = new ArrayList<>();
		try {
			// 转化成日期类型
			Date startDate = sdf.parse(startTime);
			Date endDate = sdf.parse(endTime);

			//用Calendar 进行日期比较判断
			Calendar calendar = Calendar.getInstance();
			while (startDate.getTime() <= endDate.getTime()) {

				// 把日期添加到集合
				list.add(sdf.format(startDate));

				// 设置日期
				calendar.setTime(startDate);

				//把月数增加 1
				calendar.add(Calendar.MONTH, 1);

				// 获取增加后的日期
				startDate = calendar.getTime();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}

	//excel导入 日期格式的转化
	public static Date convertExcelDateToJavaDate(double excelDate){
		Date javaDate=new Date((long)((excelDate-1)*24*60*60*1000));
		return javaDate;
	}

	public static Date convertExcelDateDayToJavaDate(double excelDate) throws ParseException {
		String pattern = "[0-9]*";
		String dateStr = String.valueOf((long) (excelDate));
		if(dateStr.matches(pattern)){//进入Excel的日期格式1900-01-01的区分格式

			Date originalDate = org.apache.commons.lang3.time.DateUtils.parseDate("1900-01-01 00:00:00", "yyyy-MM-dd HH:mm:ss");
			long long1 = originalDate.getTime();
			long dateLong = long1 + ( (Long.valueOf(dateStr) - 2 ) * 24 * 60 * 60 * 1000 );
			System.out.println(new Date(dateLong));
			return new Date(dateLong);
		}else{//进入Excel的文本格式
			return org.apache.commons.lang3.time.DateUtils.parseDate(dateStr, "yyyy-MM-dd");
		}
	}


	public static long getTwoTimeBetMin(String newTime,String oldTime){
		try {
			Date date=DateUtils.parseDate(newTime,"yyyy-MM-dd HH:mm:ss");
			long d1=date.getTime();
			Date date1=DateUtils.parseDate(oldTime,"yyyy-MM-dd HH:mm:ss");
			long d2=date1.getTime();
			long between_days=(d2-d1)/(1000*60);
			return between_days;
		}catch (Exception e){
             e.printStackTrace();
		}
		return 0l;
	}

	public static List<Long> calcBetween(Date begin, Date end) {
		long day = cn.hutool.core.date.DateUtil.between(begin, end, DateUnit.DAY);
		long hour = cn.hutool.core.date.DateUtil.between(begin, end, DateUnit.HOUR)-day*24;
		Long minute = cn.hutool.core.date.DateUtil.between(begin, end, DateUnit.MINUTE)-day*24*60-hour*60;
		return Arrays.asList(day, hour, minute);
	}


}
