package com.gyee.runeconomy.util;

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;

/**
 * 项目名称：nxfd 类名称：DateUtils 类描述： 创建人：石林 创建时间：2015-3-30 上午11:42:54 修改人：shilinno1
 * 修改时间：2015-3-30 上午11:42:54 修改备注：
 */
public class DateUtils {

    private static final String format = "yyyy-MM-dd";
    private static final String format1 = "yyyy-MM-dd HH:mm:ss";
    private static final String format2 = "MM/dd/yyyy HH:mm:ss";

    // 第一次调用get将返回null

    private static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>();

    // 获取线程的变量副本，如果不覆盖initialValue，第一次get返回null，故需要初始化一个SimpleDateFormat，并set到threadLocal中

    public static SimpleDateFormat getFormat() {

        SimpleDateFormat df = (SimpleDateFormat) threadLocal.get();

        if (df == null) {
            df = new SimpleDateFormat(format);
            threadLocal.set(df);
        }
        df.setLenient(false);
        return df;

    }

    public static SimpleDateFormat getFormat1() {

        SimpleDateFormat df1 = (SimpleDateFormat) threadLocal.get();

        if (df1 == null) {
            df1 = new SimpleDateFormat(format1);
            threadLocal.set(df1);
        }
        df1.setLenient(false);
        return df1;

    }

    public static SimpleDateFormat getFormat2() {

        SimpleDateFormat df2 = (SimpleDateFormat) threadLocal.get();

        if (df2 == null) {
            df2 = new SimpleDateFormat(format2);
            threadLocal.set(df2);
        }
        df2.setLenient(false);
        return df2;

    }

    public static Date pareDateNoHours(String date) {

        SimpleDateFormat df2 = new SimpleDateFormat(format);
        try {
            return df2.parse(date);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    private DateUtils() {
    }

    /**
     * 获取系统日期（无时分秒毫秒）
     *
     * @return
     */
    public static Date today() {
        return truncate(now());
    }

    /**
     * 获取系统时间
     *
     * @return
     */
    public static Date now() {
        return new Date();
    }

    /**
     * 根据年月日生成日期对象
     *
     * @param y
     * @param m
     * @param d
     * @return
     */
    public static Date cons(int y, int m, int d) {
        Calendar cal = Calendar.getInstance();
        cal.set(y, m, d, 0, 0, 0);
        return cal.getTime();
    }

    public static String toDate(Date date) {
        return getFormat1().format(date);
    }

    public static String toDate2(Date date) {
        return getFormat2().format(date);
    }

    public static String toDate1(Date date) {
        return getFormat().format(date);
    }

    /**
     * 根据年月日时分秒生成日期对象
     *
     * @param y
     * @param m
     * @param d
     * @param h
     * @param mi
     * @param s
     * @return
     */
    public static Date cons(int y, int m, int d, int h, int mi, int s) {
        Calendar cal = Calendar.getInstance();
        cal.set(y, m, d, h, mi, s);
        return cal.getTime();
    }

    /**
     * 将指定时间转化为 Calendar
     *
     * @param date
     * @return
     */
    public static Calendar getCal(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }

    /**
     * 将时间的时分秒毫秒字段去掉
     *
     * @param date
     * @return
     */
    public static Date truncate(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 去掉日期中日及下级字段
     *
     * @param date
     * @return
     */
    public static Date truncDay(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 去掉日期中的月及下级字段
     *
     * @param date
     * @return
     */
    public static Date truncMonth(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, 0);
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 在指定时间上加指定的天数
     *
     * @param date
     * @param day
     * @return
     */
    public static Date addDays(Date date, int day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, day);
        return cal.getTime();
    }

    /**
     * 在指定的时间上加指定的月数
     *
     * @param date
     * @param month
     * @return
     */
    public static Date addMonths(Date date, int month) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, month);
        return cal.getTime();
    }

    /**
     * 在指定的时间上加指定的月数
     *
     * @param date
     * @return
     */
    public static Date addYears(Date date, int year) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.YEAR, year);
        return cal.getTime();
    }

    /**
     * 在指定时间上加指定的小时
     *
     * @param date
     * @return
     */
    public static Date addHours(Date date, int hour) {
        return new Date(date.getTime() + hour * 3600 * 1000);
    }

    /**
     * 在指定时间上加指定的分钟
     *
     * @param date
     * @return
     */
    public static Date addMinutes(Date date, int m) {
        return new Date(date.getTime() + m * 60 * 1000);
    }

    /**
     * 在指定时间上加指定的秒
     *
     * @param date
     * @return
     */
    public static Date addSeconds(Date date, int s) {
        return new Date(date.getTime() + s * 1000);
    }

    /**
     * 计算两个时间之间差的天数(取整后)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int daysDiff(Date d1, Date d2) {
        return (int) Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 60 * 24 * 1000));
    }

    public static int daysDiff1(Date d1, Date d2) {
        return (int) Math.ceil(Math.abs((d1.getTime() - d2.getTime())) / (60 * 60 * 24 * 1000));
    }

    /**
     * 计算两个时间之间差的小时数(取整后)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int hoursDiff(Date d1, Date d2) {
        return (int) Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 60 * 1000));
    }

    public static double hoursDiff1(Date d1, Date d2) {
        return Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (double) (60 * 60 * 1000));
    }

    public static double hoursDiff2(Date d1, Date d2) {
        return Math.abs((d1.getTime() - d2.getTime())) / (double) (60 * 60 * 1000);
    }

    /**
     * 计算两个时间之间差的分钟数(取整后)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int minutesDiff(Date d1, Date d2) {
        return (int) Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 1000));
    }

    /**
     * 计算两个时间之间差的分钟数(取整后)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static double minutesDiff2(Date d1, Date d2) {
        return Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (60 * 1000));
    }

    /**
     * 计算两个时间之间差的毫秒数(取整后)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long millisecondDiff(Date d1, Date d2) {
        return Math.abs(d1.getTime() - d2.getTime());
    }

    /**
     * 计算两个时间之间差的秒数(取整后)
     *
     * @param d1
     * @param d2
     * @return
     */
    public static long secondsDiff(Date d1, Date d2) {
        return (long) Math.floor(Math.abs((d1.getTime() - d2.getTime())) / (1000));
    }

    /**
     * 计算两个时间之间的月差
     *
     * @param d1
     * @param d2
     * @return
     */
    public static int monthsDiff(Date d1, Date d2) {
        Calendar cal1 = Calendar.getInstance();
        Calendar cal2 = Calendar.getInstance();
        cal1.setTime(d1);
        cal2.setTime(d2);

        return (int) Math.abs((cal1.get(Calendar.YEAR) - cal2.get(Calendar.YEAR)) * 12 + cal1.get(Calendar.MONTH) - cal2.get(Calendar.MONTH));

    }

    /**
     * 获得指定时间的月数
     *
     * @param date
     * @return
     */
    public static int getMonth(Date date) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        return cd.get(Calendar.MONTH);
    }

    /**
     * 获得指定时间的年数
     *
     * @param date
     * @return
     */
    public static int getYear(Date date) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        return cd.get(Calendar.YEAR);
    }

    /**
     * 获取指定时间的天数
     *
     * @param date
     * @return
     */
    public static int getDay(Date date) {
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        return cd.get(Calendar.DAY_OF_MONTH);
    }

    public static int getCurrentMonthLastDay() {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    public static int getMonthDays(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.set(DateUtils.getYear(date), DateUtils.getMonth(date), DateUtils.getDay(date));
        int dayst = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        return dayst;
    }

    /**
     * 获取当前月的第一天
     *
     * @return
     */
    public static String getCurrtenFirstDay() {

        Calendar c = Calendar.getInstance();
        // c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);
        return getFormat().format(c.getTime());
    }

    /**
     * 获取当前月的最后一天
     *
     * @return
     */
    public static String getCurrtenLastDay() {

        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        return getFormat().format(ca.getTime());
    }

    /**
     * 获取当前月的第一天
     *
     * @return
     */
    public static Date getCurrtenFirstDate() {

        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 1);
        return c.getTime();
    }

    /**
     * 获取当前月的最后一天
     *
     * @return
     */
    public static Date getCurrtenLastDate() {

        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }

    public static Date parseDate(String date) {
        try {
            return getFormat().parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseDate1(String date) {
        try {
            return getFormat1().parse(date);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseDate5(String date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        try {
            Date parsedDate = format.parse(date);
            return parsedDate;
            // 对解析后的日期对象进行后续操作
        } catch (ParseException e) {
            e.printStackTrace();
            // 处理解析异常
        }
        return null;
    }

    public static Date parseDate2(String date) {
        try {
            return getFormat2().parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date parseLongToDate(long time) {
        return new Date(time);
    }

    /**
     * 转换Edna时间格式为标准格式
     *
     * @param pointTime
     * @return
     */
    public static String convertEdnaTime2(String pointTime, Boolean isNoSec) {
        StringBuffer sb = new StringBuffer();
        String[] dt = pointTime.split(" ");
        String[] ymd = dt[0].split("-");
        String[] hms = dt[1].split(":");
        sb.append(ymd[0]).append("-");
        if (ymd[1].length() == 1) {
            sb.append("0").append(ymd[1]);
        } else {
            sb.append(ymd[1]);
        }
        if (ymd[2].length() == 1) {
            sb.append("-").append("0").append(ymd[2]);
        } else {
            sb.append("-").append(ymd[2]);
        }
        if (hms[0].length() == 1) {
            sb.append(" ").append("0").append(hms[0]);
        } else {
            sb.append(" ").append(hms[0]);
        }
        if (hms[1].length() == 1) {
            sb.append(":").append("0").append(hms[1]);
        } else {
            sb.append(":").append(hms[1]);
        }

        if (isNoSec) {
            sb.append(":").append("00");
        } else {
            if (hms[2].length() == 1) {
                sb.append(":").append("0").append(hms[2]);
            } else {
                sb.append(":").append(hms[2]);
            }
        }

        return sb.toString();
    }

    /**
     * 转换Edna时间格式为标准格式
     *
     * @param pointTime
     * @return
     */
    public static String convertEdnaTime(String pointTime, Boolean isNoSec) {
        String date = getFormat().format(new Date());
        StringBuffer sb = new StringBuffer();
        String[] dt = pointTime.split(" ");
        String[] ymd = dt[0].split("/");
        String[] hms = dt[1].split(":");
        if (ymd[2].length() == 2) {
            sb.append(date.substring(0, 2)).append(ymd[2]).append("-");
        }
        if (ymd[0].length() == 1) {
            sb.append("0").append(ymd[0]);
        } else {
            sb.append(ymd[0]);
        }
        if (ymd[1].length() == 1) {
            sb.append("-").append("0").append(ymd[1]);
        } else {
            sb.append("-").append(ymd[1]);
        }
        if (hms[0].length() == 1) {
            sb.append(" ").append("0").append(hms[0]);
        } else {
            sb.append(" ").append(hms[0]);
        }
        if (hms[1].length() == 1) {
            sb.append(":").append("0").append(hms[1]);
        } else {
            sb.append(":").append(hms[1]);
        }

        if (isNoSec) {
            sb.append(":").append("00");
        } else {
            if (hms[2].length() == 1) {
                sb.append(":").append("0").append(hms[2]);
            } else {
                sb.append(":").append(hms[2]);
            }
        }

        return sb.toString();
    }


    // 获取两个时间相差分钟数
    public static int getTimeDiff(String oldTime, String newTime) {
        int diff = 0;
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long NTime = 0;
        long OTime = 0;
        try {
            NTime = df.parse(newTime).getTime();
            //从对象中拿到时间
            OTime = df.parse(oldTime).getTime();
            diff = (int) (Math.abs((NTime-OTime))/1000/60);
        } catch (ParseException e) {
        }

        return diff;
    }

    /**
     * 获取时间月开始时间和月结束时间
     *
     * @param time 格式为 "yyyy-MM"，例如 "2024-11"
     * @return 包含开始时间和结束时间的字符串数组
     */
    public static String[] generateTimeRange(String time) {
        // 时间格式化器，用于生成输出格式
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        // 解析输入的年月，并补充为该月的第一天
        String timeWithDay = time + "-01";  // 补充为 "yyyy-MM-01"
        LocalDate firstDayOfMonth = LocalDate.parse(timeWithDay, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

        // 开始时间：time月的第一天，00:00:00
        String startTime = firstDayOfMonth.atStartOfDay().format(outputFormatter);

        // 结束时间：time月的最后一天，23:59:59
        LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth());
        String endTime = lastDayOfMonth.atTime(23, 59, 59).format(outputFormatter);

        // 返回字符串数组，包含开始时间和结束时间
        return new String[]{startTime, endTime};
    }

    /**
     * 获取时间去年同期
     *
     * @param time
     * @return
     */
    public static String subtractOneYear(String time) {
        // 定义时间格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");

        // 使用 YearMonth 解析和操作年月
        YearMonth yearMonth = YearMonth.parse(time, formatter);
        YearMonth result = yearMonth.minusYears(1);

        // 格式化为字符串
        return result.format(formatter);
    }

    /**
     * 获取指定时间段内的天数
     *
     * @param timeRange 包含开始时间和结束时间的字符串数组
     * @return 天数
     */
    public static int getDaysInMonth(String[] timeRange) {
        // 解析开始时间和结束时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate startDate = LocalDate.parse(timeRange[0], formatter);
        LocalDate endDate = LocalDate.parse(timeRange[1], formatter);

        // 计算开始时间到结束时间的天数差
        return (int) (ChronoUnit.DAYS.between(startDate, endDate) + 1);
    }
    // 工具方法：格式化时间戳
    public static String formatTimestamp(long timestamp) {
        LocalDateTime dateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault());
        return dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
    public static Date[] sjcl (String kssj,String jssj) throws ParseException {

        // 时间格式，格式是 "yyyy-MM-dd HH:mm"
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        // 将字符串转换为 Date 对象
        Date kssjDate = sdf.parse(kssj);
        Date jssjDate = sdf.parse(jssj);

        // 创建 Calendar 对象
        Calendar kssjCalendar = Calendar.getInstance();
        Calendar jssjCalendar = Calendar.getInstance();

        // 将 Date 设置到 Calendar 对象中
        kssjCalendar.setTime(kssjDate);
        jssjCalendar.setTime(jssjDate);

        // 设置 endDate 为当天的 23:59:59
        jssjCalendar.set(Calendar.HOUR_OF_DAY, 23);
        jssjCalendar.set(Calendar.MINUTE, 59);
        jssjCalendar.set(Calendar.SECOND, 59);
        jssjCalendar.set(Calendar.MILLISECOND, 999);

        // 获取 startDate 和 endDate
        Date startDate = kssjCalendar.getTime();
        Date endDate = jssjCalendar.getTime();
        return new Date[] {startDate, endDate};
    }
    public static String convertEdnaTime(String pointTime) {
        return convertEdnaTime2(pointTime, false);
    }

    public static void main(String[] args) {
        System.out.println(DateUtils.getMonthDays(DateUtils.today()));
    }

}
