package com.hfkj.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {
	 
	private static Logger log = LoggerFactory.getLogger(DateUtil.class);
	public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	public static SimpleDateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM");
	public static SimpleDateFormat dateFormatDB = new SimpleDateFormat("yyyyMMdd");// 数据库使用的日期格式
	public static SimpleDateFormat dataTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static final String Y_M_D = "yyyy-MM-dd";
	public static final String Y_M_D_HM = "yyyy-MM-dd HH:mm";
	public static final String Y_M_D_HMS = "yyyy-MM-dd HH:mm:ss";
	public static final String YMD = "yyyyMMdd";
	public static final String YMDHM = "yyyyMMddHHmm";
	public static final String YMDHMS = "yyyyMMddHHmmss";
	public static final String YYMMDDH = "yyMMddHH";
	public static final String ymd = "yyyy/MM/dd";
	public static final String ymd_HM = "yyyy/MM/dd HH:mm";
	public static final String ymd_HMS = "yyyy/MM/dd HH:mm:ss";
	public static final String ymd_point = "yyyy.MM.dd";
	public static final String md_point = "MM.dd";
	public static final String Y_M = "yyyy-MM";
	private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");


	public static Integer getThisYear(){
		Calendar calendar = Calendar.getInstance();
		return calendar.get(Calendar.YEAR);
	}
	public static String date2String(Date date,String format) {
		String str = null;
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		if(date != null){
			str = sdf.format(date);
		}
		return str;
	}
	 
	public static Date long2Date(Long time) throws Exception{
		if(time != null){
			return new Date(time);
		}else{
			return null;
		}
	}
	/**
	 * 获取最近几个月的日期，例如今天是2018年6月26日，输入-3，返回最近三个月的日期2018年3月26日
	 * @param delta
	 * @return
	 * @throws Exception 
	 */
	public static Date getLastMonth(int delta){
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.MONTH, delta);
			return calendar.getTime();
		} catch (Exception e) {
			log.error("getLastMonth error",e);
		}
		return null;
	}

	/**
	 * 字符串转时间
	 *
	 * @param date
	 * @param format
	 * @return
	 */
	public static Date StringToDate(String date, String format) {
		if(StringUtils.isBlank(date)){
			return null;
		}
		SimpleDateFormat formatter = new SimpleDateFormat(format);
		ParsePosition pos = new ParsePosition(0);
		Date strtodate = formatter.parse(date, pos);
		return strtodate;
	}

	/**
	 * @throws
	 * @Title: getDateBegin
	 * @Description: TODO(获取指定日期开始)
	 * @author: 杜江
	 * @param: [date]
	 * @return: java.util.Date
	 */
	public static Date getDateBegin(Date date) {
		LocalDate nowDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		//设置零点
		LocalDateTime beginTime = LocalDateTime.of(nowDate, LocalTime.MIN);
		//将时间进行格式化
		ZoneId zoneId = ZoneId.systemDefault();
		ZonedDateTime zdt = beginTime.atZone(zoneId);
		return Date.from(zdt.toInstant());
	}

	/**
	 * date转换成UNIX时间戳，毫秒
	 *
	 * @param date
	 * @return
	 * @throws ParseException
	 */
	public static Long timesTamp(Date date,String formats) {
		try {
			// 获取系统时间
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
					formats);
			String time = simpleDateFormat.format(date);
			Long timeStemp =  (simpleDateFormat.parse(time).getTime());
			return timeStemp;
		}catch (Exception e){
			return null;
		}

	}

	/**
	 * @MethodName timesTamp
	 * @Description:date转换成UNIX时间戳，毫秒
	 * @param dateString
	 * @return: java.lang.Long
	 * @Author: Sum1Dream
	 * @Date: 2024/7/3 下午6:10
	 */
	public static Long timesTamp(String dateString) {
		try {
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date date = formatter.parse(dateString);
            return date.getTime();
		}catch (Exception e){
			return null;
		}

	}

	/**
	 * 获取某月第一天日期
	 * @return Date
	 */
	public static Date getFisrtDayOfMonth(String dateString) throws ParseException {
		DateFormat dateFormat = new SimpleDateFormat("yyyyMM");
		Date inputDate = dateFormat.parse(dateString);

		Calendar cal = Calendar.getInstance();
		cal.setTime(inputDate);

		int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
		cal.set(Calendar.DAY_OF_MONTH, firstDay);

		return cal.getTime();
	}

	/**
	 * @throws
	 * @Title: addSeconds
	 * @Description: TODO(指定日期 ， 指定秒后的时间)
	 * @author: 杜江
	 * @param: [date, seconds]
	 * @return: java.util.Date
	 */
	public static Date addSeconds(Date date, int seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, seconds);
		return calendar.getTime();
	}

	/**
	 * 获取某月最后一天日期
	 * @return Date
	 */
	public static Date getLastDayOfMonth(String dateString) throws ParseException {
		DateFormat dateFormat = new SimpleDateFormat("yyyyMM");
		Date inputDate = dateFormat.parse(dateString);

		Calendar cal = Calendar.getInstance();
		cal.setTime(inputDate);

		int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
		cal.set(Calendar.DAY_OF_MONTH, lastDay);

		return cal.getTime();
	}

	/**
	 *
	 * @Title: getDaysOfMonth
	 * @Description: TODO(获取某月天数)
	 * @author: 杜江
	 * @param: [date]
	 * @return: int
	 * @throws
	 */
	public static int getDaysOfMonth(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * @throws
	 * @Title: getDateBegin
	 * @Description: TODO(获取指定日期结束)
	 * @author: 杜江
	 * @param: [date]
	 * @return: java.util.Date
	 */
	public static Date getDateEnd(Date date) {
		LocalDate nowDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		//设置最大时间
		LocalDateTime beginTime = LocalDateTime.of(nowDate, LocalTime.MAX);
		//将时间进行格式化
		ZoneId zoneId = ZoneId.systemDefault();
		ZonedDateTime zdt = beginTime.atZone(zoneId);
		return Date.from(zdt.toInstant());
	}

	/**
	 * 功能：传入时间字符串按所需格式返回时间
	 *
	 * @param dateStr 时间字符串
	 * @param format  跟传入dateStr时间的格式必须一样 yyyy-MM-dd HH:mm:ss | yyyy年MM月dd日 HH时mm分ss秒
	 * @return
	 */
	public static Date format(String dateStr, String format) {
		if (dateStr == null || dateStr == "") {
			return new Date();
		}
		if (dateStr == null || dateStr == "") {
			format = "yyyy-MM-dd";
		}
		Date date = null;
		try {
			DateFormat f = new SimpleDateFormat(format);
			date = f.parse(dateStr);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return date;

	}

	/**
	 * 功能：传入时间按所需格式返回时间字符串
	 *
	 * @param date   java.util.Date格式
	 * @param format yyyy-MM-dd HH:mm:ss | yyyy年MM月dd日 HH时mm分ss秒
	 * @return
	 */
	public static String format(Date date, String format) {
		String result = "";
		try {
			if (date == null) {
				date = new Date();// 如果时间为空,则默认为当前时间
			}
			if (format == null || format == "") {// 默认格式化形式
				format = "yyyy-MM-dd";
			}
			DateFormat df = new SimpleDateFormat(format);
			result = df.format(date);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 *
	 * @Title: UtcToDate
	 * @Description: 转为+8区标准时间
	 * @author:
	 * @param: [date, format]
	 * @return: java.util.Date
	 * @throws
	 */
	public static Date UtcToDate(String date, String format) {
		try {
			String newDate = date.replace("Z", " UTC");
			SimpleDateFormat formatter = new SimpleDateFormat(format);
			Date strtodate = formatter.parse(newDate);
			return strtodate;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 *
	 * @Title: getNewDate
	 * @Description: 指定日期加上制定月份得到新的日期
	 * @author:
	 * @param: [cur, addNum]
	 * @return: java.util.Date
	 * @throws
	 */
	public static Date getNewDate(Date cur,Integer addNum) {
		Calendar c = Calendar.getInstance();
		c.setTime(cur);   //设置时间
		c.add(Calendar.MONTH, addNum); //日期分钟加1,Calendar.DATE(天),Calendar.HOUR(小时)
		Date date = c.getTime(); //结果
		return date;
	}
    /**
     *
     * @Title: getTimeInterval
     * @Description: 获取本周的星期数所对应的日期
     * @author: 杜江
     * @param: [dayWeek]
     * @return: java.lang.String
     * @throws
     */
	public static String getTimeInterval(int dayWeek) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);// 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        int day = 0;
        if(dayWeek==1){
            day=-3;
        }
        if(dayWeek==2){
            day=-2;
        }
        if(dayWeek==3){
            day=-1;
        }
        if (dayWeek==4){
            day=0;
        }
        if(dayWeek==5){
            day=1;
        }
        if(dayWeek==6){
            day=2;
        }
        if(dayWeek==7){
            day=3;
        }
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() +day);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);
        return weekBegin;
	}
	/**
	 *
	 * @Title: getDayInWeek
	 * @Description: 获取今天是本周的第几天
	 * @author: 杜江
	 * @param: []
	 * @return: int
	 * @throws
	 */
	public static int getDayInWeek(){
		Date today = new Date();
		Calendar c=Calendar.getInstance();
		c.setTime(today);
		int weekday=c.get(Calendar.DAY_OF_WEEK);
		if(weekday==1){
			weekday = weekday+6;
			return weekday;
		}else{
			weekday = weekday-1;
			return weekday;
		}
	}
	/**
	 *
	 * @Title: getLastWeekInDay
	 * @Description: 获取下周的星期几的日期
	 * @author: 杜江
	 * @param: []
	 * @return: java.lang.String
	 * @throws
	 */
	public static Date getLastWeekInDay(int day){
		Calendar calendar = Calendar.getInstance();
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		int offset1 = day - dayOfWeek;
		calendar.add(Calendar.DATE, offset1 + 7);
		return calendar.getTime();
	}
     /**
      *
      * @Title: changeDate
      * @Description: 指定的日期减去天数后得到的日期
      * @author: 杜江
      * @param: [date, day]
      * @return: java.util.Date
      * @throws
      */
    public static Date reduceDate(Date date,int day) throws ParseException {
        long time = date.getTime(); // 得到指定日期的毫秒数
        day = day*24*60*60*1000; // 要减去的天数转换成毫秒数
        time-=day; // 相减得到新的毫秒数
        return new Date(time); // 将毫秒数转换成日期
    }

	/**
	 *
	 * @Title: changeDate
	 * @Description: 指定的日期加上天数后得到的日期
	 * @author: 杜江
	 * @param: [date, day]
	 * @return: java.util.Date
	 * @throws
	 */
	public static Date addDate(Date date,int day) throws ParseException {
		long time = date.getTime(); // 得到指定日期的毫秒数
		long longTime = (long)day;
		long addDay = longTime*24*60*60*1000; // 要加上的天数转换成毫秒数
		time+=addDay; // 相减得到新的毫秒数
		return new Date(time); // 将毫秒数转换成日期
	}

	/**
	 *
	 * @Title: getChinaWeek
	 * @Description: 功能：返回星期 1：星期一，2:星期二 ... 6:星期六 7:星期日
	 * @author: 杜江
	 * @param: [date]
	 * @return: int
	 * @throws
	 */
	public static int getChinaWeek(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int week = c.get(Calendar.DAY_OF_WEEK) - 1;
		if (week == 0) {
			return 7;
		} else {
			return week;
		}
	}

	/**
	 *
	 * @Title: getNextDay
	 * @Description: TODO(当前日期加一天)
	 * @author: 杜江
	 * @param: [date]
	 * @return: java.util.Date
	 * @throws
	 */
	public static Date getNextDay(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.DAY_OF_MONTH, +1);//+1今天的时间加一天
		date = calendar.getTime();
		return date;
	}

	/**
	 *
	 * @Title: getNowBegin
	 * @Description: TODO(获取今天开始时间)
	 * @author: 杜江
	 * @param: []
	 * @return: java.util.Date
	 * @throws
	 */
	public static Date getNowBegin() {
		//获取当前日期
		LocalDate nowDate = LocalDate.now();
		//设置零点
		LocalDateTime beginTime = LocalDateTime.of(nowDate, LocalTime.MIN);
		//将时间进行格式化
		ZoneId zoneId = ZoneId.systemDefault();
		ZonedDateTime zdt = beginTime.atZone(zoneId);
		return Date.from(zdt.toInstant());
	}

	/**
	 *
	 * @Title: numberChange
	 * @Description: TODO(星期转换)
	 * @author:
	 * @param: [number]
	 * @return: java.lang.String
	 * @throws
	 */
	public static String numberChange(Integer number) {
		if (number == 1) {
			return "一";
		}else if (number == 2) {
			return "二";
		}
		else if (number == 3) {
			return "三";
		}
		else if (number == 4) {
			return "四";
		}
		else if (number == 5) {
			return "五";
		}
		else if (number == 6) {
			return "六";
		}
		else if (number == 7) {
			return "日";
		}else {
			return null;
		}
	}


	/**
	 *
	 * @Title: getNowEnd
	 * @Description: TODO(获取今天结束时间)
	 * @author: 杜江
	 * @param: []
	 * @return: java.util.Date
	 * @throws
	 */
	public static Date getNowEnd() {
		//获取当前日期
		LocalDate nowDate = LocalDate.now();
		//设置最大时间
		LocalDateTime endTime = LocalDateTime.of(nowDate,LocalTime.MAX);
		//将时间进行格式化
		ZoneId zoneId = ZoneId.systemDefault();
		ZonedDateTime zdt = endTime.atZone(zoneId);
		return Date.from(zdt.toInstant());
	}

	/**
	 *       * 获取当月的 天数
	 *
	 */
	public static int getCurrentMonthDay() {
		Calendar a = Calendar.getInstance();
		a.set(Calendar.DATE, 1);
		a.roll(Calendar.DATE, -1);
		int maxDate = a.get(Calendar.DATE);
		return maxDate;
	}

	/**
	 * 获取当前月第一天日期
	 * @return Date
	 */
	public static String getCurrentMonthFirstDay() {
		Calendar c = Calendar.getInstance();
		c.add(Calendar.MONTH, 0);
		c.set(Calendar.DAY_OF_MONTH, 1);
		String first = format.format(c.getTime());
		return first;
	}

	/**
	 * 获取当前月最后一天日期
	 * @return Date
	 */
	public static String getCurrentMonthlastDay() {
		Calendar ca = Calendar.getInstance();
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
		String last = format.format(ca.getTime());
		return last;
	}

	/**
	 *
	 * @Title: getMinutesDiff
	 * @Description: 获取newTime-oldTime相差分钟数
	 * @author: gongjia
	 * @param: [oldTime, newTime]
	 * @return: int
	 * @throws
	 */
	public static long getMinutesDiff(Date oldTime, Date newTime) throws Exception{
		long oldTimeStamp = oldTime.getTime();
		long newTimeStamp = newTime.getTime();

		long diffTimeStamp = newTimeStamp - oldTimeStamp;

		return diffTimeStamp / (1000 * 60);
	}

    /**
     *
     * @Title: addDatetime
     * @Description: 1.指定日期加上'年、月、日、时、分、秒'
     *                2.'年、月、日、时、分、秒'允许负数
     *                3.下级时间会向上级传递（如增加1天25小时，实际增加2天1小时）
     *                4.无需改变的值可指定为0
     * @author: gongjia
     * @param: [date, year, month, day, hour, minute, second]
     * @return: java.util.Date
     * @throws
     */
    public static Date addDatetime(Date date, int year, int month, int day, int hour, int minute, int second) throws Exception {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        calendar.add(Calendar.YEAR, year);
        calendar.add(Calendar.MONTH, month);
        calendar.add(Calendar.DAY_OF_MONTH, day);
        calendar.add(Calendar.HOUR_OF_DAY, hour);
        calendar.add(Calendar.MINUTE, minute);
        calendar.add(Calendar.SECOND, second);

        return calendar.getTime();
    }

    public static Date getDateArea(Date oldDate) throws Exception {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String strOld = format.format(oldDate);

		return format.parse(strOld);
	}

	public static Date addMinute(Date time, int minute) {
		Calendar c = Calendar.getInstance();
		c.setTime(time); //设置时间
		c.add(Calendar.MINUTE, minute); //日期分钟加1,Calendar.DATE(天),Calendar.HOUR(小时)
		Date date = c.getTime(); //结果
		return date;
	}

	/**
	 * 通过时间秒毫秒数判断两个时间的间隔
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDaysByMillisecond(Date date1,Date date2)
	{
		int days = (int)Math.ceil(((date2.getTime() - date1.getTime()) / (1000*3600*24)));
		return days;
	}

	/**
	 * date2比date1多的天数
	 * @param date1
	 * @param date2
	 * @return
	 */
	public static int differentDays(Date date1,Date date2)
	{
		Calendar cal1 = Calendar.getInstance();
		cal1.setTime(date1);

		Calendar cal2 = Calendar.getInstance();
		cal2.setTime(date2);
		int day1= cal1.get(Calendar.DAY_OF_YEAR);
		int day2 = cal2.get(Calendar.DAY_OF_YEAR);

		int year1 = cal1.get(Calendar.YEAR);
		int year2 = cal2.get(Calendar.YEAR);
		if(year1 != year2)   //同一年
		{
			int timeDistance = 0 ;
			for(int i = year1 ; i < year2 ; i ++)
			{
				if(i%4==0 && i%100!=0 || i%400==0)    //闰年
				{
					timeDistance += 366;
				}
				else    //不是闰年
				{
					timeDistance += 365;
				}
			}

			return timeDistance + (day2-day1) ;
		}
		else    //不同年
		{
			System.out.println("判断day2 - day1 : " + (day2-day1));
			return day2-day1;
		}
	}


	/**
	 * 字符串日期转换成中文格式日期
	 *
	 * @param date 字符串日期 yyyy-MM-dd
	 * @return yyyy年MM月dd日
	 * @throws Exception
	 */
	public static String dateToCnDate(Date date) {
		try {
			String dateString = date2String(date, Y_M_D);
			String result = "";
			String[] cnDate = new String[]{"〇", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
			String ten = "十";
			String[] dateStr = dateString.split("-");
			for (int i = 0; i < dateStr.length; i++) {
				for (int j = 0; j < dateStr[i].length(); j++) {
					String charStr = dateStr[i];
					String str = String.valueOf(charStr.charAt(j));
					if (charStr.length() == 2) {
						if (charStr.equals("10")) {
							result += ten;
							break;
						} else {
							if (j == 0) {
								if (charStr.charAt(j) == '1')
									result += ten;
								else if (charStr.charAt(j) == '0')
									result += "";
								else
									result += cnDate[Integer.parseInt(str)] + ten;
							}
							if (j == 1) {
								if (charStr.charAt(j) == '0')
									result += "";
								else
									result += cnDate[Integer.parseInt(str)];
							}
						}
					} else {
						result += cnDate[Integer.parseInt(str)];
					}
				}
				if (i == 0) {
					result += "年";
					continue;
				}
				if (i == 1) {
					result += "月";
					continue;
				}
				if (i == 2) {
					result += "日";
					continue;
				}
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}


	/**
	 * 判断当前时间是否在[startTime, endTime]区间，注意时间格式要一致
	 *
	 * @param nowTime 当前时间
	 * @param startTime 开始时间
	 * @param endTime 结束时间
	 * @return
	 * @author jqlin
	 */
	public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
		if (nowTime.getTime() == startTime.getTime()
				|| nowTime.getTime() == endTime.getTime()) {
			return true;
		}

		Calendar date = Calendar.getInstance();
		date.setTime(nowTime);

		Calendar begin = Calendar.getInstance();
		begin.setTime(startTime);

		Calendar end = Calendar.getInstance();
		end.setTime(endTime);

		if (date.after(begin) && date.before(end)) {
			return true;
		} else {
			return false;
		}
	}


	public static void main(String[] args) throws Exception {
		String a = "51130319931105651X";
		System.out.println(a.substring(6,10));
		System.out.println(a.substring(10,12));
		System.out.println(a.substring(12,14));
	}

}
