package cn.hmsoft.ltc.common.util;

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

/*******************************
 * 日期辅助类
 * 
 * @author zxq
 * @create 2018-04-05 22:53:22
 * @version 5.0.0
 * @email: revisit@126.com
 * @Company: www.hmsoft.cn
 */
public class DateHelper {
	public final static String ChinaDateString = "yyyy月MM月dd日";
	public final static DateTimeFormatter ChinaFormatter = DateTimeFormatter.ofPattern(ChinaDateString);
	
	public final static String ShortDateString = "yyyy-MM-dd";
	public final static DateTimeFormatter ShortDateFormatter = DateTimeFormatter.ofPattern(ShortDateString);
	public final static String ShortDateStringWithoutSplit = "yyyyMMdd";
	public final static DateTimeFormatter ShortDateStringWithoutSplitFormatter = DateTimeFormatter
			.ofPattern(ShortDateStringWithoutSplit);

	public final static String ShortTimeString = "HH:mm:ss";
	public final static DateTimeFormatter ShortTimeFormatter = DateTimeFormatter.ofPattern(ShortTimeString);
	public final static String ShortTimeStringWithoutSplit = "HHmmss";
	public final static DateTimeFormatter ShortTimeStringWithoutSplitFormatter = DateTimeFormatter
			.ofPattern(ShortTimeStringWithoutSplit);

	public final static String LongDateString = "yyyy-MM-dd HH:mm:ss";
	public final static DateTimeFormatter LongDateFormatter = DateTimeFormatter.ofPattern(LongDateString);
	
	public final static String LongDateStringWithoutSplit = "yyyyMMddHHmmss";
	public final static DateTimeFormatter LongDateStringWithoutSplitFormatter = DateTimeFormatter
			.ofPattern(LongDateStringWithoutSplit);
	
	public final static String MillisecondDateString = "yyyyMMddHHmmssSSS";
	public final static DateTimeFormatter MillisecondDateFormatter = DateTimeFormatter.ofPattern(MillisecondDateString);
	
	public final static String HourMinuteString = "HH:mm";
	public final static DateTimeFormatter HourMinuteFormatter = DateTimeFormatter.ofPattern(HourMinuteString);

	public final static String MillisecondString = "HHmmssSSS";
	public final static DateTimeFormatter MillisecondFormatter = DateTimeFormatter.ofPattern(MillisecondString);
	
	public final static int HourZoneOffset = Calendar.getInstance().get(java.util.Calendar.ZONE_OFFSET) / 3600000;
	// 星期名字
	public final static String[] WeekNames = new String[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
	// 月份名字
	public final static String[] MonthNames = new String[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月",
			"十一月", "十二月" };
	/***************************
	 * 一天的秒数
	 */
	public final static int DaySeconds = 86400;
	/*************************
	 * 一个小时的秒数
	 */
	public final static int HourSeconds = 3600;

	

	/*****************************
	 * 将字符串转换为日期
	 * 
	 * @param value 2018-01-02 23:10:20格式的字符串
	 *            
	 * @return
	 */
	public static LocalDateTime parseDateTime(String value) {
		try {
			return LocalDateTime.parse(value, LongDateFormatter);
		} catch (Exception e) {
		}
		return null;
	}
	
	/*****************************
	 * 将字符串转换为日期
	 * 
	 * @param value  yyyyMMddHHmmss
	 *            
	 * @return
	 */
	public static LocalDateTime parseDateTimeNoSplit(String value) {
		try {
			return LocalDateTime.parse(value, LongDateStringWithoutSplitFormatter);
		} catch (Exception e) {
		}
		return null;
	}

	/*****************************
	 * 将字符串转换为日期
	 * 
	 * @param value 2018-01-02格式的字符串
	 *            
	 * @return
	 */
	public static LocalDate parseDate(String value) {
		try {
			return LocalDate.parse(value, ShortDateFormatter);
		} catch (Exception e) {
		}
		return null;
	}
	
	/*****************************
	 * 将字符串转换为日期
	 * 
	 * @param value 20180102格式的字符串
	 *            
	 * @return
	 */
	public static LocalDate parseDateNoSplit(String value) {
		try {
			return LocalDate.parse(value, ShortDateStringWithoutSplitFormatter);
		} catch (Exception e) {
		}
		return null;
	}

	/*****************************
	 * 将字符串转换为时间
	 * 
	 * @param value
	 *            20:02:01格式的字符串
	 * @return
	 */
	public static LocalTime parseTime(String value) {
		try {
			return LocalTime.parse(value, ShortTimeFormatter);
		} catch (Exception e) {
			try {
				return LocalTime.parse(value, HourMinuteFormatter);
			} catch (Exception ex) {
			}
		}
		return null;
	}

	/*****************************
	 * 将字符串转换为时间
	 * 
	 * @param value
	 *            20:02格式的字符串
	 * @return
	 */
	public static LocalTime parseHourTime(String value) {
		try {
			return LocalTime.parse(value, HourMinuteFormatter);
		} catch (Exception e) {
		}
		return null;
	}

	/***************************
	 * 将日期转换为字符串  yyyy-MM-dd
	 */
	public static String format(LocalDate value) {
		try {
			return value.format(ShortDateFormatter);
		} catch (Exception e) {
		}
		return null;
	}
	
	public static String formatToChina(LocalDate value) {
		try {
			return value.format(ChinaFormatter);
		} catch(Exception e) {
		}
		return null;
	}
	
	/***************************
	 * 将日期转换为字符串  HH:mm
	 */
	public static String formatHourMinute(LocalTime value) {
		try {
			return value.format(HourMinuteFormatter);
		} catch (Exception e) {
		}
		return null;
	}
	
	/***************************
	 * 将日期转换为字符串  yyyyMMdd
	 */
	public static String formatNoSplit(LocalDateTime value) {
		try {
			return value.format(ShortDateStringWithoutSplitFormatter);
		} catch (Exception e) {
		}
		return null;
	}

	/***************************
	 * 将日期转换为字符串  yyyyMMdd
	 */
	public static String formatLongNoSplit(LocalDateTime value) {
		try {
			return value.format(LongDateStringWithoutSplitFormatter);
		} catch (Exception e) {
		}
		return null;
	}
	/***************************
	 * 将时间转换为字符串
	 */
	public static String format(LocalTime value) {
		try {
			return value.format(ShortTimeFormatter);
		} catch (Exception e) {
		}
		return null;
	}
	
	/***************************
	 * 将时间转换为字符串 HHmmssSSS
	 */
	public static String formatMilliseconds(LocalDateTime value) {
		try {
			return value.format(MillisecondFormatter);
		} catch (Exception e) {
		}
		return null;
	}

	/***************************
	 * 将时间转换为字符串
	 */
	public static String format(LocalDateTime value) {
		try {
			return value.format(LongDateFormatter);
		} catch (Exception e) {
		}
		return null;
	}

	/************************
	 * java.util.Date --> java.time.LocalDateTime
	 */
	public static LocalDateTime toLocalDateTime(java.util.Date date) {
		Instant instant = date.toInstant();
		ZoneId zone = ZoneId.systemDefault();
		return LocalDateTime.ofInstant(instant, zone);
	}

	/************************
	 * java.util.Date -->java.time.LocalDate
	 */
	public static LocalDate toLocalDate(java.util.Date date) {
		return toLocalDateTime(date).toLocalDate();
	}

	/************************
	 * java.util.Date -->java.time.LocalTime
	 */
	public static LocalTime toLocalTime(java.util.Date date) {
		return toLocalDateTime(date).toLocalTime();
	}

	/************************
	 * java.time.LocalDateTime -->java.util.Date
	 */
	public static Date toDate(LocalDateTime localDateTime) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDateTime.atZone(zone).toInstant();
		return Date.from(instant);
	}

	/************************
	 * java.time.LocalDate -->java.util.Date
	 */
	public static Date toDate(LocalDate localDate) {
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
		return Date.from(instant);
	}

	/************************
	 * java.time.LocalTime -->java.util.Date
	 */
	public static Date toDate(LocalTime localTime) {
		LocalDate localDate = LocalDate.now();
		LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDateTime.atZone(zone).toInstant();
		return Date.from(instant);
	}
	
	/************************
	 * LocalDateTime ：计算时间差
	 */
	public static Long calTimeDiff(LocalDateTime end, LocalDateTime start, int compare_type) {
		Long value = 0L;
		Duration duration = Duration.between(start, end);
		if (compare_type == 14) 
			value = duration.toMillis();
		if (compare_type == 13)
			value = duration.toMillis() / 1000;
		if (compare_type == 12)
			value = duration.toMinutes();
		if (compare_type == 10)
			value = duration.toHours();
		if (compare_type == 5)
			value = duration.toDays();
		if (value < 0) {
			return 0 - value;
		}
		return value;
	}
	
	/************************
	 * LocalDateTime ：计算时间差
	 */
	public static Long calTimeDiff(LocalTime end, LocalTime start, int compare_type) {
		Long value = 0L;
		Duration duration = Duration.between(start, end);
		if (compare_type == 14) 
			value = duration.toMillis();
		if (compare_type == 13)
			value = duration.toMillis() / 1000;
		if (compare_type == 12)
			value = duration.toMinutes();
		if (compare_type == 10)
			value = duration.toHours();
		if (compare_type == 5)
			value = duration.toDays();
		if (value < 0) {
			return 0 - value;
		}
		return value;
	}
	
	/***************
	 * 格式化短时间格式
	 */
	public static String formatShortString(LocalDateTime date) {
		return date.format(ShortTimeFormatter);
	}
	
	/***************
	 * 格式化短时间格式
	 */
	public static String formatHourMinute(LocalDateTime date) {
		return date.format(HourMinuteFormatter);
	}
	
	public static LocalDateTime fromMillis(long mills) {
		Instant instant = Instant.ofEpochMilli(mills);
		return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
	}
	
	public static long toMillis(LocalDateTime dateTime) {
		return dateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
	}
	
	public static LocalDateTime toLocalDateTime(LocalDate localDate, LocalTime localTime) {
		return LocalDateTime.of(localDate, localTime);
	}

	public static boolean isBetween(LocalDateTime dateTime, LocalDateTime startDateTime,
			LocalDateTime endDateTime) {
		return dateTime.isAfter(startDateTime) && dateTime.isBefore(endDateTime);
	}
	
	public static boolean isBetween(LocalTime time, LocalTime startTime,
			LocalTime endTime) {
		return time.isAfter(startTime) && time.isBefore(endTime);
	}
	
	public static boolean isBetween(LocalDate time, LocalDate startTime,
			LocalDate endTime) {
		return time.isAfter(startTime) && time.isBefore(endTime);
	}
	
	/***************
	 * 时间相加减
	 */
	public static LocalTime addValues(LocalTime time,Long values) {
		time = time.plusMinutes(values);
		return time;
	}
	
}
