package com.mmc.csf.common.util.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 作者 geDuo
 * @version 创建时间：2021年7月17日 下午5:28:19
 * @explain 日期时间工具类
 */
public class TDateUtil {
	public static final String ONE_WEEK = "oneweek";
	public static final String ONE_MONTH = "onemonth";
	public static final String THREE_MONTH = "threemonth";
	public static final String SIX_MONTH = "sixmonth";
	public static final String ONE_YEAR = "oneyear";

	public static String getCurrentDate() {
		SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm");// 设置日期格式
		String date = df.format(new Date());// new Date()为获取当前系统时间
		return date;
	}

	public static String getCurrentDateByType(String format) {
		SimpleDateFormat df = new SimpleDateFormat(format);// 设置日期格式
		String date = df.format(new Date());// new Date()为获取当前系统时间
		return date;
	}

	public static String getCurrentDateMidd() {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
		String date = df.format(new Date());// new Date()为获取当前系统时间
		return date;
	}

	public static Date getDate(String str, String format) {
		Date date = null;
		try {
			SimpleDateFormat df = new SimpleDateFormat(format);// 设置日期格式
			// String dates=df.format(new Date());// new Date()为获取当前系统时间
			date = df.parse(str);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * date类型转字符串
	 */
	public static String getDateStr(Date date, String type) {
		SimpleDateFormat format = new SimpleDateFormat(type);
		String s = format.format(date);
		return s;
	}

	/**
	 * 根据日期获得随机数
	 */
	public static Integer getDateRandom(Date date, String format, int count) {
		String code = "";
		for (int i = 0; i < count; i++) {
			code = code + (int) (Math.random() * 9);
		}
		code = TDateUtil.getDateStr(date, format) + code;
		return Integer.parseInt(code);
	}

	/**
	 * 10位数的秒转日期字符
	 * 
	 * @param mss
	 * @return
	 */
	public static Date dateFromSecond(long sceondTime) {
		return new Date(sceondTime * 1000);
	}

	/**
	 * 10位数的秒转日期字符
	 * 
	 * @param mss
	 * @return
	 */
	public static String dateFromSecondStr(long sceondTime) {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(sceondTime * 1000));
	}

	/**
	 * 秒转时分秒
	 * 
	 * @param secondTime
	 * @return
	 */
	public static String hmsFromSecond(Integer secondTime) {
		Integer hour = secondTime / 60 / 60;
		Integer minutes = secondTime / 60 % 60;
		Integer remainingSeconds = secondTime % 60;
		return (hour + "h" + minutes + "min" + remainingSeconds + "s");
	}

	public static String hmsFromSecondFormat(long secondTime) {
		long day = secondTime / 60 / 60 / 24;
		long hour = secondTime / 60 / 60 % 24;
		long minutes = secondTime / 60 % 60;
		long remainingSeconds = secondTime % 60;
		if (day > 0) {
			return (day + "天" + hour + "小时" + minutes + "分" + remainingSeconds + "秒");
		}
		return (hour + "小时" + minutes + "分" + remainingSeconds + "秒");
	}

	/**
	 * 两个日期的相差秒数
	 * 
	 * @param maxDate
	 * @param minDate
	 * @return
	 */
	public static long calLastedTime(Date maxDate, Date minDate) {
		long a = maxDate.getTime();
		long b = minDate.getTime();
		long c = (a - b) / 1000;
		return c;
	}

	/**
	 * 获取某个月的月底最后一天的时间
	 */
	public static Date getMonthLatestDay(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取当前月最后一天
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
		String last = format.format(ca.getTime());
		Date dates = getDate(last, "yyyy-MM-dd");
		return dates;
	}

	/**
	 * 某个时间 加N天
	 */
	public static Date nextNumDay(Date d, int num) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date date = null;
		try {
			Date now = d;
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(now);
			calendar.add(Calendar.DAY_OF_MONTH, num);
			String last = format.format(calendar.getTime());
			date = getDate(last, "yyyy-MM-dd");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 某天个时间加 N 小时
	 * @param now
	 * @param num
	 * @return
	 */
	public static Date addHourTime(Date now,int num){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(now);
			calendar.add(Calendar.HOUR,num);
			String last = format.format(calendar.getTime());
			date = getDate(last, "yyyy-MM-dd HH:mm:ss");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * 某个时间加n个月加n天(负数为减)
	 */
	@SuppressWarnings("static-access")
	public static Date getMonthNDayN(Date date, int month, int day) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Date news = null;
		try {
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(date);
			calendar.add(Calendar.MONTH, month);
			calendar.add(calendar.DATE, day);
			String last = format.format(calendar.getTime());
			news = getDate(last, "yyyy-MM-dd");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return news;
	}

	/**
	 * 时间戳-计算小时
	 */
	public static long getDistanceTime(long time1, long time2) {
		long diff = 0;
		long day = 0;
		long hour = 0;
		if (time1 < time2) {
			diff = time2 - time1;
		} else {
			diff = time1 - time2;
		}
		day = diff / (24 * 60 * 60 * 1000);
		hour = (diff / (60 * 60 * 1000) - day * 24);
		return hour;
	}

	/**
	 * 两个时间之间相差距离多少天
	 * 
	 * @param one 时间参数 1：
	 * @param two 时间参数 2：
	 * @return 相差天数
	 */
	public static int distanceDays(Date one, Date two) {
		int days = 0;
		long time1 = one.getTime();
		long time2 = two.getTime();
		long diff;
		if (time1 < time2) {
			diff = time2 - time1;
		} else {
			diff = time1 - time2;
		}
		days = new Long(diff / (1000 * 60 * 60 * 24)).intValue();
		return days;
	}

	public static Date nextNumDateTime(Date d, int num) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = null;
		try {
			Date now = d;
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(now);
			calendar.add(Calendar.DAY_OF_MONTH, num);
			String last = format.format(calendar.getTime());
			date = getDate(last, "yyyy-MM-dd HH:mm:ss");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	public static String createYearWeek(String startStr, String endStr) {
		if (startStr == null || "".equals(startStr) || endStr == null || "".equals(endStr)) {
			return "起止日期不能为空";
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date start = null;
		Date end = null;
		Date startDate;
		Date endDate;
		int dayOfWeek;
		boolean goOn = true;
		int no = 0;
		try {
			start = sdf.parse(startStr);
			end = sdf.parse(endStr);
		} catch (ParseException e) {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
			try {
				start = simpleDateFormat.parse(startStr);
				end = simpleDateFormat.parse(endStr);
			} catch (ParseException pe) {
				pe.printStackTrace();
			}
		}
		if (start.compareTo(end) > -1) {
			return "结束日期必须大于开始日期";
		}
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(start);
		dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
		List<Map<String, String>> weekList = new ArrayList<>();
		if (dayOfWeek > 1 && dayOfWeek < 7) {
			do {
				startDate = start;
				calendar.add(Calendar.DATE, (8 - dayOfWeek));
				endDate = calendar.getTime();
				no += 1;
				Map<String, String> map = new HashMap<>();
				map.put("startOfWeek", sdf.format(startDate));
				map.put("weekNo", no + "");
				if (endDate.compareTo(end) < 0) {
					map.put("endOfWeek", sdf.format(endDate));
					weekList.add(map);
					calendar.add(Calendar.DATE, 1);
					start = calendar.getTime();
					dayOfWeek = 2;
				} else {
					map.put("endOfWeek", sdf.format(end));
					weekList.add(map);
					goOn = false;
				}
			} while (goOn);
		} else {
			no += 1;
			startDate = start;
			if (dayOfWeek == 1) {
				endDate = start;
			} else {
				calendar.add(Calendar.DATE, 1);
				endDate = calendar.getTime();
			}
			Map<String, String> map = new HashMap<>();
			map.put("startOfWeek", sdf.format(startDate));
			map.put("endOfWeek", sdf.format(endDate));
			map.put("weekNo", no + "");
			weekList.add(map);
			calendar.add(Calendar.DATE, 1);
			start = calendar.getTime();
			do {
				startDate = start;
				calendar.add(Calendar.DATE, 6);
				endDate = calendar.getTime();
				no += 1;
				map = new HashMap<>();
				map.put("startOfWeek", sdf.format(startDate));
				map.put("weekNo", no + "");
				if (endDate.compareTo(end) < 0) {
					map.put("endOfWeek", sdf.format(endDate));
					weekList.add(map);
					calendar.add(Calendar.DATE, 1);
					start = calendar.getTime();
				} else {
					map.put("endOfWeek", sdf.format(end));
					weekList.add(map);
					goOn = false;
				}
			} while (goOn);
		}
		return weekList.toString();
	}

	/**
	 * 获取起止日期
	 * 
	 * @param sdf    需要显示的日期格式
	 * @param date   需要参照的日期
	 * @param n      最近n周
	 * @param option 0 开始日期；1 结束日期
	 * @param k      0 包含本周 1 不包含本周
	 * @return
	 */
	public static String getFromToDate(SimpleDateFormat sdf, Date date, int n, int option, int k) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK) - 1;
		int offset = 0 == option ? 1 - dayOfWeek : 7 - dayOfWeek;
		int amount = 0 == option ? offset - (n - 1 + k) * 7 : offset - k * 7;
		calendar.add(Calendar.DATE, amount);
		return sdf.format(calendar.getTime());
	}

	/**
	 * 根据当前日期获得最近n周的日期区间（包含本周）
	 * 
	 * @param n
	 * @param sdf
	 * @return
	 */
	public static String getNWeekTimeInterval(int n, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);// 设置日期格式
		String beginDate = getFromToDate(sdf, new Date(), n, 0, 0);
		String endDate = getFromToDate(sdf, new Date(), n, 1, 0);
		return beginDate + "," + endDate;
	}

	/**
	 * 根据当前日期获得最近n周的日期区间（不包含本周）
	 * 
	 * @param n
	 * @param sdf
	 * @return
	 */
	public static String getNWeekTimeIntervalTwo(int n, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);// 设置日期格式
		String beginDate = getFromToDate(sdf, new Date(), n, 0, 1);
		String endDate = getFromToDate(sdf, new Date(), n, 1, 1);
		return beginDate + "," + endDate;
	}

	/**
	 * 根据当前日期获得本周的日期区间（本周周一和周日日期）
	 * 
	 * @param sdf
	 * @return
	 */
	public static String getThisWeekTimeInterval(String format) {
		return getNWeekTimeInterval(1, format);
	}

	/**
	 * 根据当前日期获得上周的日期区间（上周周一和周日日期）
	 * 
	 * @param sdf
	 * @return
	 */
	public static String getLastWeekTimeInterval(String format) {
		return getNWeekTimeIntervalTwo(1, format);
	}

	/**
	 * 获取某个日期最近一个的星期日
	 * 
	 * @return
	 */
	public static Date getLatestWeekend(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		Date endDate = TDateUtil.nextNumDay(date, w * -1);
		return endDate;
	}

	/**
	 * 获取N周的星期一的日期(正加负减)
	 * 
	 * @param date
	 * @return
	 */
	public static Date getMinMonday(Date date, int weekNum) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
		Date endDate = TDateUtil.nextNumDay(date, w * -1);
		Date startDate = TDateUtil.nextNumDay(endDate, (weekNum * 7) + 1);
		return startDate;
	}

	/**
	 * 获取某个月加几个月后一号的日期
	 */
	@SuppressWarnings("static-access")
	public static Date getAddMonThDay(Date date, int i) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(calendar.MONTH, i);
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		String last = format.format(calendar.getTime());
		date = getDate(last, "yyyy-MM-dd");
		return date;
	}

	/**
	 * 某个月最后一天
	 */
	public static Date getAnyMonthLastDay(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取当前月最后一天
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
		String last = format.format(ca.getTime());
		date = getDate(last, "yyyy-MM-dd");
		return date;
	}

	public static Date getDate(Date date, String type) {
		SimpleDateFormat format = new SimpleDateFormat(type);
		String s = format.format(date);
		return getDate(s, type);
	}

	/**
	 * 获取去年今天的日期
	 */
	public static Date getLastYearTodayDate() {
		Calendar instance = Calendar.getInstance();
		instance.add(Calendar.YEAR,-1);
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		String s = format.format(instance.getTime());
		return getDate(s, "yyyy-MM-dd");
	}

	/**
	 * 获取昨天的日期
	 * @param type
	 * @return
	 */
	public static String getYesterdayDateByType(String type){
		Calendar instance = Calendar.getInstance();
		instance.add(Calendar.DAY_OF_MONTH,-1);
		Date time = instance.getTime();
		SimpleDateFormat format = new SimpleDateFormat(type);
		return format.format(time);
	}

	/**
	 * 判断两个时间是不是在同一个月
	 */
	public static boolean isSameMonth(Date date1, Date date2) {

		Calendar c = Calendar.getInstance();
		c.setTime(date1);
		int month1 = c.get(Calendar.MONTH);
		c.setTime(date2);
		int month2 = c.get(Calendar.MONTH);
		if (month1 == month2) {
			return true;
		}
		return false;
	}

	/**
	 * 间隔天数
	 * @param startTime
	 * @param endTime
	 * @return
	 */
	public static int isolateDayNum(String startTime, String endTime){
		Date startDate = getDate(startTime, "yyyy-MM-dd");
		Date endDate = getDate(endTime, "yyyy-MM-dd");
		long differentMillis = endDate.getTime() - startDate.getTime();
		long dayNum = differentMillis/(1000*60*60*24);
		return (int)dayNum;
	}

	/**
	 * 获取某月最后一天的时间
	 * @param yearMonth
	 * @return
	 */
	public static String getLastDateTimeOfMonth(String yearMonth){
		SimpleDateFormat format0 = new SimpleDateFormat("yyyy-MM");
		SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar instance = Calendar.getInstance();
		try {
			Date parse = format0.parse(yearMonth);
			instance.setTime(parse);
			instance.set(Calendar.DAY_OF_MONTH,  instance.getActualMaximum(Calendar.DAY_OF_MONTH));
			instance.set(Calendar.HOUR_OF_DAY, 23);
			instance.set(Calendar.MINUTE, 59);
			instance.set(Calendar.SECOND, 59);
			String format = format1.format(instance.getTime());
			return format;
		} catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}

	public static Date getStrToDate(String str){
			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
			Date date = null;
			try {
				if (str==null){
					date = null;
				}else {
					date = dateFormat.parse(str);
				}
			} catch (ParseException e) {
				e.printStackTrace();
			}
			return date;
	}

	public static int getStageByDate(Date date){
		Calendar instance = Calendar.getInstance();
		instance.setTime(date);
		//当前时间
		SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
		String format = dateFormat.format(date);
		try {
			Date currentTime = dateFormat.parse(format);

			Date parse1 = dateFormat.parse("05:00:00");
			Date parse2 = dateFormat.parse("11:00:00");

			Date parse3 = dateFormat.parse("17:00:00");
			Date parse4 = dateFormat.parse("00:00:00");

			//A:05:00-11:00 | B:11:00-17:00 | C:00:00-05:00,17:00-00:00
			if (currentTime.after(parse4) && currentTime.before(parse1) ) {
				return 3;
			}else if (currentTime.after(parse1) && currentTime.before(parse2)) {
				return 1;
			}else if(currentTime.after(parse2) && currentTime.before(parse3)){
				return 2;
			}else if(currentTime.after(parse3) && currentTime.after(parse4)){
				return 4;
			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return 0;
	}

	public static String getCurrentYear(){
		Calendar date = Calendar.getInstance();
		String year = String.valueOf(date.get(Calendar.YEAR));
		return year;
	}
}
