package com.mvc.utils;

import com.mvc.model.TAireadModel;

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

public class DateUtil {
    public static final String PATTERN_DATA_NORMAL = "yyyy-MM-dd HH:mm:ss";//常规格式
    public static final String PATTERN_DATA_UNSIGNED = "yyyyMMddHHmmss";//无符号格式

    /**
     * 取得当前时间
     *
     * @param pattern
     * @return
     */
    public static String getCurrentTime(String pattern) {
        String dateStr = "";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date now = new Date();
        dateStr = sdf.format(now);
        return dateStr;
    }

    /**
     * 根据日期和间隔，取得时间字符串
     *
     * @param date
     * @param interval
     * @param pattern
     * @return
     */
    public static String getTimeStr(Date date, int interval, String pattern) {
        String dateStr = "";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.SECOND, interval);
        dateStr = sdf.format(calendar.getTime());

        return dateStr;
    }

    /**
     * 格式化输出日期  yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @param pattern
     * @return
     */
    public static String formateDate(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    /**
     * 解析日期字符串，生成日期  yyyyMMddHHmmss
     *
     * @param dateStr
     * @param pattern
     * @return
     */
    public static Date parseTimeStr(String dateStr, String pattern) {
        Date ret = null;
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            ret = sdf.parse(dateStr);
        } catch (ParseException e) {
            ret = null;
        }
        return ret;
    }

    /**
     * 比较两个时间
     *
     * @param startTime
     * @param endTime
     * @param field
     * @return
     */
    public static int compare(Date startTime, Date endTime, int field) {
        Calendar calStart = Calendar.getInstance();
        calStart.setTime(startTime);
        Calendar calEnd = Calendar.getInstance();
        calEnd.setTime(endTime);

        return calEnd.get(field) - calStart.get(field);
    }

    /**
     * 比较时间字符串
     *
     * @param time1
     * @param time2
     * @param pattern
     * @return
     */
    public static int compareDateStr(String time1, String time2, String pattern) {
        Date date1 = parseTimeStr(time1, pattern);
        Date date2 = parseTimeStr(time2, pattern);
        return date1.compareTo(date2);
    }

    /**
     * @param kssj 开始时间
     * @param jssj 结束时间
     * @param type 类型
     * @return
     * @throws ParseException
     * @Description:计算两个时间的差值（单位 分钟）
     * @author:wh
     * @return:
     * @date 2020-9-24
     */
    public static int getMinsbetweenTime(String kssj, String jssj, String type) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(type);
        Date ksDate = sdf.parse(kssj);
        Date jsDate = sdf.parse(jssj);
        return (int) ((jsDate.getTime() - ksDate.getTime()) / 1000 / 60);

    }

    /**
     * 获取日期相差分钟数
     *
     * @param kssj
     * @param jssj
     * @return
     */
    public static long getMinsbetweenTime(Date kssj, Date jssj) {
        Instant instant1 = kssj.toInstant();
        Instant instant2 = jssj.toInstant();
        Duration duration = Duration.between(instant1, instant2);
        return duration.toMinutes();
    }

    public static int getSencondsbetweenTime(Date kssj, Date jssj) {
        return (int) ((jssj.getTime() - kssj.getTime()) / 1000);
    }


    /**
     * 根据日期和相差天数,获取一个新的日期
     *
     * @param date
     * @param num
     * @return
     */
    public static Date getOtherDateByCurrentDate(Date date, int num) {
        Calendar calendar = Calendar.getInstance();//获取日历实例
        try {
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, num);
            return calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * date加上小时得到一个新日期
     *
     * @param date
     * @param num
     * @return
     */
    public static Date getOtherDateByHour(Date date, int num) {
        Calendar calendar = Calendar.getInstance();//获取日历实例
        try {
            calendar.setTime(date);
            calendar.add(Calendar.HOUR_OF_DAY, num);
            return calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * date加上月份得到一个新日期
     *
     * @param date
     * @param num
     * @return
     */
    public static Date getOtherDateByMonth(Date date, int num) {
        Calendar calendar = Calendar.getInstance();//获取日历实例
        try {
            calendar.setTime(date);
            calendar.add(Calendar.MONTH, num);
            return calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * date加上分钟得到一个新日期
     *
     * @param date
     * @param num
     * @return
     */
    public static Date getOtherDateByMinute(Date date, int num) {
        Calendar calendar = Calendar.getInstance();//获取日历实例
        try {
            calendar.setTime(date);
            calendar.add(Calendar.MINUTE, num);
            return calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获取两个Date的小时差(含分钟)
     *
     * @param date1
     * @param date2
     * @return
     */
    public static double getTotalHoursWithMinutesAsFraction(Date date1, Date date2) {
        long diffInMillies = Math.abs(date2.getTime() - date1.getTime());
        int hours = (int) (diffInMillies / (1000 * 60 * 60));
        int minutes = (int) ((diffInMillies % (1000 * 60 * 60)) / (1000 * 60));

        return hours + (minutes / 60.0);
    }

    /**
     * 获取指定日期的0点时间
     *
     * @param date
     * @return
     */
    public static Date getMidnightDate(Date date) {
        LocalDate today = LocalDate.now();
        // 创建一个表示凌晨0点0分0秒的LocalTime对象
        LocalTime midnight = LocalTime.MIDNIGHT;
        // 结合日期和时间创建一个LocalDateTime对象
        LocalDateTime todayAtMidnight = LocalDateTime.of(today, midnight);

        return Date.from(todayAtMidnight.atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date getFirstDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    /**
     * 获取当前日期当月最后一天的日期
     *
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        // 将日期设置为下个月的第一天
        calendar.add(Calendar.MONTH, 1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);

        // 然后回退一天，得到的就是这个月的最后一天
        calendar.add(Calendar.DATE, -1);

        return calendar.getTime();
    }

    /**
     * date加上年数得到一个新日期
     *
     * @param date
     * @param year
     * @return
     */
    public static Date getOtherDateByYear(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);

        // 减少指定数量的年份
        calendar.add(Calendar.YEAR, year);

        return calendar.getTime();
    }

    /**
     * 将Date转为LocalDate
     *
     * @param date
     * @return
     */
    public static LocalDate dateToLocalDate(Date date) {
        // 首先，将Date转换为Instant
        Instant instant = date.toInstant();
        // 然后，使用ZoneId将Instant转换为ZonedDateTime
        ZoneId zoneId = ZoneId.systemDefault(); // 使用系统默认时区，或者您可以指定一个时区，例如ZoneId.of("Asia/Shanghai")
        java.time.ZonedDateTime zonedDateTime = instant.atZone(zoneId);
        // 最后，从ZonedDateTime中获取LocalDate
        return zonedDateTime.toLocalDate();
    }

    /**
     * 间隔天数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static long daysBetween(Date startDate, Date endDate) {
        // 将java.util.Date转换为java.time.LocalDate
        LocalDate startLocalDate = startDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate endLocalDate = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

        // 使用ChronoUnit计算天数差
        long daysBetween = ChronoUnit.DAYS.between(startLocalDate, endLocalDate);

        return daysBetween;
    }

    /**
     * 获取date的0点数据
     *
     * @param date
     * @return
     */
    public static Date getZeroTimeOfDay(Date date) {
        LocalDate localDate = dateToLocalDate(date);
        // 再转换回Date对象
        return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取日期的分钟数
     *
     * @param date
     * @return
     */
    public static int getMinutes(Date date) {
        // 将Date转换为LocalDateTime
        LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalTime localTime = localDateTime.toLocalTime();

        return localTime.getMinute();
    }

    /**
     * 获取日期的小时数
     *
     * @param date
     * @return
     */
    public static int getHours(Date date) {
        // 将Date转换为LocalDateTime
        LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalTime localTime = localDateTime.toLocalTime();

        return localTime.getHour();
    }

    /**
     * 获取给定日期的星期几。
     *
     * @param date 一个 java.util.Date 类型的日期
     * @return 对应的 DayOfWeek 枚举值
     */
    public static DayOfWeek getDayOfWeek(Date date) {
        LocalDate localDate = dateToLocalDate(date);
        // 返回 LocalDate 的星期几
        return localDate.getDayOfWeek();
    }

    /**
     * 获取查询条件的结束时间
     * 以当日12点为分界,过了12点则取当日数据
     * @return
     */
    public static String getQueryEndTime() {
        Date now = new Date();
        Date queryTime = DateUtil.getZeroTimeOfDay(now);//当日0点
        if (DateUtil.getMinsbetweenTime(queryTime, now) < 12 * 60) {//当前时间未过12点(理论上未完成审核,使用昨日数据)
            queryTime = DateUtil.getOtherDateByMinute(queryTime, -1);//昨日23:59(为了让用户取得昨日的数据)
        }
        return DateUtil.formateDate(queryTime, DateUtil.PATTERN_DATA_UNSIGNED);
    }

    /**
     * 获取当前日期的int值(yyyyMMdd)
     * @return
     */
    public static int getCurrentDateAsInt() {
        // 获取当前日期
        LocalDate currentDate = LocalDate.now();
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        // 格式化当前日期
        String formattedDate = currentDate.format(formatter);
        // 将格式化后的字符串转换为 int
        return Integer.parseInt(formattedDate);
    }

    public static void main(String[] args) {
        Date date = new Date();

        TAireadModel a = new TAireadModel();
        a.setSampleTime(date);

        TAireadModel b = new TAireadModel();
        b.setSampleTime(date);

        if(a.getSampleTime().equals(b.getSampleTime())){
            System.out.println("a equals b");
        }

        if(a.getSampleTime().compareTo(b.getSampleTime())==0){
            System.out.println("a compareTo b");
        }

        b.setSampleTime(DateUtil.getOtherDateByHour(date, 0));

        if(a.getSampleTime().equals(b.getSampleTime())){
            System.out.println("a equals b");
        }

        if(a.getSampleTime().compareTo(b.getSampleTime())==0){
            System.out.println("a compareTo b");
        }

        /*List<TAireadModel> aireadModelList = new ArrayList<>();
        Date date = new Date();
        TAireadModel a = new TAireadModel();
        a.setSampleTime(date);

        TAireadModel b = new TAireadModel();
        b.setSampleTime(date);

        aireadModelList.add(a);
        aireadModelList.add(b);

        Date date1 = new Date();
        TAireadModel d = new TAireadModel();
        d.setSampleTime(date1);
        aireadModelList.add(d);

        aireadModelList = aireadModelList.stream()
                .collect(Collectors.toMap(
                        TAireadModel::getSampleTime, // keyMapper
                        Function.identity(), // valueMapper
                        (existing, replacement) -> existing // mergeFunction
                ))
                .values()
                .stream()
                .collect(Collectors.toList());*/
    }
}
