package com.huatek.busi.common.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期相关工具类
 *
 * @author anker_cheng
 * @date 2019/07/31
 */
public class DateUtil {

    public static final String PATTERN_DATE = "yyyy-MM-dd";
    public static final String PATTERN_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_PATTERN_DATE_TIME = "yyyyMMddHHmmss";

    public static LocalDateTime atEndOfDay(LocalDate date) {
        return LocalDateTime.of(date, LocalTime.MAX);
    }

    public static LocalDateTime atStartOfDay(LocalDate date) {
        return LocalDateTime.of(date, LocalTime.MIN);
    }
    /**
     * 获取当前日期的前一天
     *
     * @return Date
     */
    public static Date getBeforeDate() {
        LocalDate localDate = LocalDate.now().minusDays(1);
        return toDate(localDate);
    }

    /**
     * 获取当时间{date}的前{interval}天
     *
     * @param date
     *            时间
     * @param interval
     *            间隔天数
     * @return
     */
    public static Date getIntervalDate(Date date, int interval) {
        LocalDate localDate = toLocalDate(date).minusDays(interval);
        return toDate(localDate);
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static String getCurrentHourDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, 0);
        Date today = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String result = sdf.format(today);
        return result;
    }

    /**
     * 获取前半年的时间
     *
     * @return
     */
    public static String getHalfYearDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH, -6);
        Date today = calendar.getTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String result = sdf.format(today);
        return result;
    }

    public static Date getStartDate() {
        LocalDate localDate = LocalDate.now().minusDays(1);
        LocalDateTime localDateTime = localDate.atStartOfDay();
        return toDate(localDateTime);
    }

    public static Date getCurrentDate() {
        return toDate(LocalDateTime.of(LocalDate.now(), LocalTime.of(0, 0)));
    }

    public static Date getCurrentDate(LocalDate data) {
        return toDate(LocalDateTime.of(data.minusDays(-1), LocalTime.of(0, 0)));
    }

    public static Date getEndDate() {
        LocalDate localDate = LocalDate.now().minusDays(1);
        LocalDateTime localDateTime = atEndOfDay(localDate);
        return toDate(localDateTime);
    }

    public static Date getEndDate(LocalDate data) {
//    	LocalDate localDate = data.minusDays(1);
        LocalDateTime localDateTime = atEndOfDay(data);
        return toDate(localDateTime);
    }

    public static LocalDate toLocalDate(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
    }

    public static LocalDateTime toLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }

    public static Date toDate(LocalDate localDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    public static LocalDateTime toLocalDateTime(LocalDate localDate) {
        Date date = toDate(localDate);
        LocalDateTime localDateTime = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
        return localDateTime;
    }

    public static Date toDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static String format(LocalDateTime localDateTime) {
        return format(localDateTime, PATTERN_DATE_TIME);
    }

    public static String formatLcoalDateTime(LocalDateTime localDateTime) {
        return format(localDateTime, PATTERN_DATE);
    }

    public static String format(LocalDate localDate) {
        return format(localDate, PATTERN_DATE);
    }

    public static String format(Date date, String pattern) {
        if(date == null) {
            return null;
        }
        return DateFormatUtils.format(date, pattern);
    }

    public static String format(Date date) {
        return format(date, PATTERN_DATE_TIME);
    }

    public static String getFormatDate(LocalDateTime date) {
    	return format(date, DEFAULT_PATTERN_DATE_TIME);
    }

    public static String format(LocalDate localDate, String pattern) {
        if(localDate == null) {
            return null;
        }
        return localDate.format(DateTimeFormatter.ofPattern(pattern));
    }

    public static String format(LocalDateTime localDateTime, String pattern) {
        if (localDateTime == null) {
            return null;
        }
        return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    //格式化LocalDate
    public static LocalDate format(String localDateTime) {
    	if (StringUtils.isEmpty(localDateTime)) {
            return null;
        }
    	return LocalDate.parse(localDateTime, DateTimeFormatter.ofPattern(PATTERN_DATE));
    }

    public static LocalDateTime monthStartTime(LocalDate day) {
        return LocalDate.of(day.getYear(), day.getMonth(), 1).atStartOfDay();
    }

    public static LocalDateTime monthEndTime(LocalDate day) {
        return day.with(TemporalAdjusters.lastDayOfMonth()).plusDays(1).atStartOfDay();
    }

    /**
     * 获取当前月份第一天
     */
    public static LocalDateTime getMonthStartDay() {
    	LocalDate startDayOfCurrentMouth = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth());
    	return LocalDateTime.of(startDayOfCurrentMouth, LocalTime.MIN);
    }
    /**
     * 获取当前月份最后一天
     */
    public static LocalDateTime getMonthLastDay() {
    	LocalDate lastDayOfCurrentMouth = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth());
    	return LocalDateTime.of(lastDayOfCurrentMouth, LocalTime.MAX);
    }

    public static LocalDate parseLocalDate(String date) {
        return LocalDate.parse(date, DateTimeFormatter.ofPattern(PATTERN_DATE));
    }

    /**
     * 获取当前时间前一个月
     */
    public static LocalDateTime getMinusMonths(String exportTime) {
	     LocalDate beginDateTime = LocalDate.parse(exportTime, DateTimeFormatter.ofPattern(PATTERN_DATE));
	     return LocalDateTime.of(beginDateTime.minusMonths(1), LocalTime.MIN);
    }

    public static String formatDuring(long mss) {
        long days = mss / (1000 * 60 * 60 * 24);
        long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
        long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
        long seconds = (mss % (1000 * 60)) / 1000;
        return days + " days " + hours + " hours " + minutes + " minutes " + seconds + " seconds ";
    }

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

    /**
     * 得到当前年份字符串 格式（yyyy）
     * @return
     */
    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");
    }

    /**
     * 获取年月日 格式：yyyyMMdd
     * @return
     */
    public static String getYYMMDDTime() {
        return getYear() + getMonth() + getDay();
    }

    /**
     * 时间差
     * @param startTime
     * @param endTime
     * @return
     */
    public static long getTimeDiff(String startTime, String endTime){

        // 获取日期
        Date date1 = parseDate(startTime, "yyyy-MM-dd HH:mm:ss");
        Date date2 = parseDate(endTime, "yyyy-MM-dd HH:mm:ss");

        // 获取相差的天数
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date1);
        long timeInMillis1 = calendar.getTimeInMillis();
        calendar.setTime(date2);
        long timeInMillis2 = calendar.getTimeInMillis();
        return (timeInMillis2 - timeInMillis1) / (1000L*3600L*24L);
    }

    public static Date parseDate(String dateStr, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date;
        try {
            date = sdf.parse(dateStr);
        } catch (Exception e) {
            throw new RuntimeException("日期转化错误");
        }
        return date;
    }

    /**
     * 验证时间格式是否正确
     * @param str
     * @param dateFormat
     * @return
     */
    public static boolean isValidDate(String str, String dateFormat) {
        boolean convertSuccess = true;
        SimpleDateFormat format = new SimpleDateFormat(dateFormat);
        try {
            format.setLenient(false);
            format.parse(str);
        } catch (ParseException e) {
            convertSuccess=false;
        }
        return convertSuccess;
    }

    public static LocalDateTime formatLocalDateTime(String time){
        try {
            LocalDateTime parse = LocalDateTime.parse(time);
            return parse;
        }catch (Exception e){

        }
        try {
            LocalDate localDate = LocalDate.parse(time);
            LocalDateTime parse = localDate.atStartOfDay();
            return parse;
        }catch (Exception e){

        }
        return null;
    }

    public static void main(String[] args) {
		System.out.println(atEndOfDay(LocalDate.now()));
	}
}
