/**
 * 
 */
package com.pcloud.common.utils;

import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import com.pcloud.common.utils.string.StringUtil;

/**
 * @描述：jdk8中新增的日期处理类,更安全、更精确也更明确
 * @作者：songx
 * @创建时间：2017年7月20日,上午9:11:37 @版本：1.0
 */
public class LocalDateUtils {

	private static final DateTimeFormatter TIME = DateTimeFormatter.ofPattern("HHmmss");
	private static final DateTimeFormatter SHORT_MILLISECOND = DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS");
	private static final DateTimeFormatter SHORT_DATETIME = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
	private static final DateTimeFormatter DATETIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	private static final DateTimeFormatter SHORT_DATE = DateTimeFormatter.ofPattern("yyyyMMdd");
	private static final DateTimeFormatter DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd");

	/**
	 * 获取当前的日期字符串(yyyy-MM-dd)
	 * 
	 * @return
	 */
	public static String getDateNow() {
		return LocalDate.now().format(DATE);
	}

	/**
	 * 获取当前的日期字符串(yyyyMMdd)
	 * 
	 * @return
	 */
	public static String getShortDateNow() {
		return LocalDate.now().format(SHORT_DATE);
	}

	/**
	 * 获取当前的时间字符串(HHmmss)
	 * 
	 * @return
	 */
	public static String getShortTimeNow() {
		return LocalDateTime.now().format(TIME);
	}

	/**
	 * 获取当前的日期字符串(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @return
	 */
	public static String getDateTimeNow() {
		return LocalDateTime.now().format(DATETIME);
	}

	/**
	 * 获取当前的日期字符串(yyyyMMddHHmmss)
	 * 
	 * @return
	 */
	public static String getShortDateTimeNow() {
		return LocalDateTime.now().format(SHORT_DATETIME);
	}

	/**
	 * 获取当前的日期字符串(yyyyMMddHHmmssSSS)
	 * 
	 * @return
	 */
	public static String getYmdhmss() {
		return LocalDateTime.now().format(SHORT_MILLISECOND);
	}

	/**
	 * 时间戳转换成字符串格式的时间
	 * 
	 * @param time
	 * @return
	 */
	public static String convertToString(long time) {
		return LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()).toString().replace("T", " ");
	}

	/**
	 * 转换成Stirng类型的时间字符串(yyyy-MM-dd HH:mm:ss)
	 * 
	 * @param localDateTime
	 * @return
	 */
	public static String convertToString(LocalDateTime localDateTime) {
		if (localDateTime == null) {
			return null;
		}
		return localDateTime.format(DATETIME);
	}

	/**
	 * 获取当前日前多少天以前的日期
	 * 
	 * @param days
	 * @return
	 */
	public static LocalDate getMinusDays(long days) {
		LocalDate localDate = LocalDate.now();
		return localDate.minusDays(days);
	}

	/**
	 * 获取当前日前多少小时以前的日期
	 * 
	 * @param minutes
	 * @return
	 */
	public static LocalDateTime getMinusHours(long hours) {
		LocalDateTime localDateTime = LocalDateTime.now();
		return localDateTime.minusHours(hours);
	}

	/**
	 * 获取当前日前多少分钟以前的日期
	 * 
	 * @param minutes
	 * @return
	 */
	public static LocalDateTime getMinusMinutes(long minutes) {
		LocalDateTime localDateTime = LocalDateTime.now();
		return localDateTime.minusMinutes(minutes);
	}

	/**
	 * 获取指定日前多少天以后的日期
	 * 
	 * @param date
	 * @param days
	 * @return
	 */
	public static LocalDateTime getPlusDays(Date date, long days) {
		LocalDateTime localDateTime = convertDateTime(date);
		return localDateTime.plusDays(days);
	}

	/**
	 * Date转换为localDate
	 * 
	 * @param date
	 * @return
	 */
	public static LocalDate convertDate(Date date) {
		return convertDateTime(date).toLocalDate();
	}

	/**
	 * Date转换为localDateTime
	 * 
	 * @param date
	 * @return
	 */
	public static LocalDateTime convertDateTime(Date date) {
		if (date == null) {
			return null;
		}
		Instant instant = date.toInstant();
		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
	}

	/**
	 * string转换为localDateTime
	 * 
	 * @param dateTime
	 * @return
	 */
	public static LocalDateTime convertDateTime(String dateTime) {
		if (StringUtil.isEmpty(dateTime)) {
			return null;
		}
		if (!dateTime.contains("T")) {
			dateTime = dateTime.replace(" ", "T");
		}
		return LocalDateTime.parse(dateTime);
	}

	/**
	 * 判断当前日期是否在指定日前之前,含当前日期
	 * 
	 * @param date
	 * @return
	 */
	public static boolean isBefore(Date date) {
		if (date == null) {
			return false;
		}
		LocalDateTime localDateTime = convertDateTime(date);
		return LocalDateTime.now().isBefore(localDateTime);
	}

	/**
	 * 判断当前日期是否在指定日前之后,含当前日期
	 * 
	 * @param date
	 * @return
	 */
	public static boolean isAfter(Date date) {
		if (date == null) {
			return false;
		}
		LocalDateTime localDateTime = convertDateTime(date);
		return LocalDateTime.now().isAfter(localDateTime);
	}

	/**
	 * 判断当前日期是否在指定日前之后,含当前日期
	 * 
	 * @param localDateTime
	 * @return
	 */
	public static boolean isAfter(LocalDateTime localDateTime) {
		if (localDateTime == null) {
			return false;
		}
		return LocalDateTime.now().isAfter(localDateTime);
	}

	/**
	 * 判断第一个日期是否在第二个日前之后
	 * 
	 * @param firstDateTime
	 * @param secondDateTime
	 * @return
	 */
	public static boolean isAfter(LocalDateTime firstDateTime, LocalDateTime secondDateTime) {
		if (firstDateTime == null || secondDateTime == null) {
			return false;
		}
		return firstDateTime.isAfter(secondDateTime);
	}

	/**
	 * 判断第一个日期是否在第二个日前之后
	 * 
	 * @param firstDateTime
	 * @param secondDateTime
	 * @return
	 */
	public static boolean isAfter(String firstDateTime, String secondDateTime) {
		if (firstDateTime == null || secondDateTime == null) {
			return false;
		}
		return convertDateTime(firstDateTime).isAfter(convertDateTime(secondDateTime));
	}

	/**
	 * 判断第一个日期是否在第二个日前之后
	 * 
	 * @param firstDateTime
	 * @param secondDateTime
	 * @return
	 */
	public static boolean isAfter(Date firstDateTime, Date secondDateTime) {
		if (firstDateTime == null || secondDateTime == null) {
			return false;
		}
		return convertDateTime(firstDateTime).isAfter(convertDateTime(secondDateTime));
	}

	/**
	 * 判断当前日期是否在一定的日期之内,包含前后的两天，例：2017-07-15->[2017-07-01, 2017-07-15]
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static boolean isInIncludeDate(LocalDate startDate, LocalDate endDate) {
		if (startDate == null || endDate == null) {
			return false;
		}
		LocalDate nowTime = LocalDate.now();
		if (nowTime.isAfter(startDate.plusDays(-1)) && nowTime.isBefore(endDate.plusDays(1))) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断当前日期是否在一定的日期之内,包含前后的两天，例：2017-07-15->[2017-07-01, 2017-07-15]
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static boolean isInIncludeDateString(String startDate, String endDate) {
		return isInIncludeDate(LocalDate.parse(startDate), LocalDate.parse(endDate));
	}

	/**
	 * 判断当前日期是否在一定的日期之内,不包含前后的两天，例：2017-07-15->(2017-07-01, 2017-07-15)
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static boolean isInBetweenDate(LocalDate startDate, LocalDate endDate) {
		if (startDate == null || endDate == null) {
			return false;
		}
		LocalDate nowTime = LocalDate.now();
		if (nowTime.isAfter(startDate) && nowTime.isBefore(endDate)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断当前日期是否在一定的日期之内,不包含前后的两天，例：2017-07-15->(2017-07-01, 2017-07-15)
	 * 
	 * @param startDate
	 * @param endDate
	 * @return
	 */
	public static boolean isInBetweenDateString(String startDate, String endDate) {
		return isInBetweenDate(LocalDate.parse(startDate), LocalDate.parse(endDate));
	}

	/**
	 * 判断当前日期是否在一定的日期之内， 例：2017-07-15 12:12:12->(2017-07-01 12:12:12, 2017-07-15
	 * 12:12:12)
	 * 
	 * @param startDateTime
	 * @param endDateTime
	 * @return
	 */
	public static boolean isInBetweenDateTime(LocalDateTime startDateTime, LocalDateTime endDateTime) {
		if (startDateTime == null || endDateTime == null) {
			return false;
		}
		LocalDateTime nowTime = LocalDateTime.now();
		if (nowTime.isAfter(startDateTime) && nowTime.isBefore(endDateTime)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断当前日期是否在一定的日期之内， 例：2017-07-15 12:12:12->(2017-07-01 12:12:12, 2017-07-15
	 * 12:12:12)
	 * 
	 * @param startDateTime
	 * @param endDateTime
	 * @return
	 */
	public static boolean isInBetweenDateTime(Date startDateTime, Date endDateTime) {
		return isInBetweenDateTime(convertDateTime(startDateTime), convertDateTime(endDateTime));
	}

	/**
	 * 判断当前日期是否在一定的日期之内， 例：2017-07-15 12:12:12->(2017-07-01 12:12:12, 2017-07-15
	 * 12:12:12)
	 * 
	 * @param startDateTime
	 * @param endDateTime
	 * @return
	 */
	public static boolean isInBetweenDateTimeString(String startDateTime, String endDateTime) {
		return isInBetweenDateTime(LocalDateTime.parse(startDateTime), LocalDateTime.parse(endDateTime));
	}

	/**
	 * 获取两个时间差，天，时，分
	 * 
	 * @param stratDateTime
	 * @param endDateTime
	 * @return
	 */
	public static long[] getDatePoor(LocalDateTime stratDateTime, LocalDateTime endDateTime) {
		if (stratDateTime == null || stratDateTime == null) {
			return null;
		}
		Duration duration = Duration.between(stratDateTime, endDateTime);
		// 计算差多少天
		long day = duration.toDays();
		// 计算差多少小时
		long hour = duration.toHours() - day * 24;
		// 计算差多少分钟
		long min = duration.toMinutes() - duration.toHours() * 60;
		return new long[] { day, hour, min };
	}

	/**
	 * 获取指定时间与当前日期相差多少小时
	 * 
	 * @param date
	 * @return
	 */
	public static long getHourPoor(Date date) {
		if (date == null) {
			return -1;
		}
		return getHourPoor(convertDateTime(date));
	}

	/**
	 * 获取指定时间与当前日期相差多少小时
	 * 
	 * @param dateTime
	 * @return
	 */
	public static long getHourPoor(LocalDateTime dateTime) {
		if (dateTime == null) {
			return -1;
		}
		Duration duration = Duration.between(dateTime, LocalDateTime.now());
		return duration.toHours();
	}

	/**
	 * 获取指定时间与当前日期相差多少天
	 * 
	 * @param date
	 * @return
	 */
	public static long getDayPoor(Date date) {
		if (date == null) {
			return -1;
		}
		return getDayPoor(convertDateTime(date));
	}

	/**
	 * 获取指定时间与当前日期相差多少天
	 * 
	 * @param dateTime
	 * @return
	 */
	public static long getDayPoor(LocalDateTime dateTime) {
		if (dateTime == null) {
			return -1;
		}
		Duration duration = Duration.between(dateTime, LocalDateTime.now());
		return duration.toDays();
	}

}
