package com.yuchen.saas.park.service.util;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * @author 吕海泉
 * @create 2020/12/30 16:11
 */
public class WsDateUtil {

    static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    /**
     * 获取指定时间戳所在月份开始的时间戳/秒
     * @param dateTimeMillis 指定时间戳/毫秒
     * @return
     */
    public static Long getMonthBegin(Long dateTimeMillis) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date(dateTimeMillis));

        //设置为1号,当前日期既为本月第一天
        c.set(Calendar.DAY_OF_MONTH, 1);
        //将小时至0
        c.set(Calendar.HOUR_OF_DAY, 0);
        //将分钟至0
        c.set(Calendar.MINUTE, 0);
        //将秒至0
        c.set(Calendar.SECOND,0);
        //将毫秒至0
        c.set(Calendar.MILLISECOND, 0);
        // 获取本月第一天的时间戳
        return c.getTimeInMillis() / 1000;
    }

    /**
     * 获取指定时间戳所在月份15号的时间戳/秒
     * @param dateTimeMillis 指定时间戳/毫秒
     * @return
     */
    public static Long getMonthMiddle(Long dateTimeMillis) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date(dateTimeMillis));

        //设置为当月最后一天
        c.set(Calendar.DAY_OF_MONTH, 15);
        //将小时至23
        c.set(Calendar.HOUR_OF_DAY, 23);
        //将分钟至59
        c.set(Calendar.MINUTE, 59);
        //将秒至59
        c.set(Calendar.SECOND,59);
        //将毫秒至999
        c.set(Calendar.MILLISECOND, 999);
        // 获取本月最后一天的时间戳
        return c.getTimeInMillis() / 1000;
    }

    /**
     * 获取指定时间戳所在月份结束的时间戳/秒
     * @param dateTimeMillis 指定时间戳/毫秒
     * @return
     */
    public static Long getMonthEnd(Long dateTimeMillis) {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date(dateTimeMillis));

        //设置为当月最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        //将小时至23
        c.set(Calendar.HOUR_OF_DAY, 23);
        //将分钟至59
        c.set(Calendar.MINUTE, 59);
        //将秒至59
        c.set(Calendar.SECOND,59);
        //将毫秒至999
        c.set(Calendar.MILLISECOND, 999);
        // 获取本月最后一天的时间戳
        return c.getTimeInMillis() / 1000;
    }

    /**
     * 获取上一个月1号0点0分0秒的时间戳
     * @param dateTimeMillis
     * @return
     */
    public static Long getPreviousMonthBegin(Long dateTimeMillis){
        Date date = new Date(dateTimeMillis);
        date.setDate(1);
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        if(date.getMonth() - 1 <= 0){
            date.setYear(date.getYear() - 1);
            date.setMonth(12);
        }else {
            date.setMonth(date.getMonth() - 1);
        }
        return date.getTime() / 1000;
    }

    /**
     * 获取上两个月1号0点0分0秒的时间戳
     * @param dateTimeMillis
     * @return
     */
    public static Long getTowMonthBegin(Long dateTimeMillis){
        Date date = new Date(dateTimeMillis);
        date.setDate(1);
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        if(date.getMonth() - 1 <= 0){
            date.setYear(date.getYear() - 1);
            date.setMonth(11);
        } else if(date.getMonth() -2 <= 0) {
            date.setYear(date.getYear() - 1);
            date.setMonth(12);
        } else {
            date.setMonth(date.getMonth() - 2);
        }
        return date.getTime() / 1000;
    }
    /**
     * 获取本月的1月1号0点
     * @param dateTimeMillis
     * @return
     */
    public static Long getCurrentMonth(Long dateTimeMillis){
        Date date = new Date(dateTimeMillis);
        date.setDate(1);
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        return date.getTime() / 1000;
    }

    /**
     * 获取今日的0点0分
     * @param dateTimeMillis
     * @return
     */
    public static Long getToday(Long dateTimeMillis){
        Date date = new Date(dateTimeMillis);
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        return date.getTime() / 1000;
    }

    /**
     * 获取今日的0点0分
     * @param dateTimeMillis
     * @return
     */
    public static Long getDay(Long dateTimeMillis,Integer number){
        Date date = new Date(dateTimeMillis);
        date.setHours(0);
        date.setMinutes(0);
        date.setSeconds(0);
        date.setDate(date.getDate() - number);
        return date.getTime() / 1000;
    }






    /**
     * 获取当前日期
     * @return
     */
    public static String getCurrentDate() {
        Date date = new Date();
        return sdf.format(date);
    }

    /**
     * 获取当天开始时间
     * @return
     */
    public static Date getDayBegin(){
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 0);//0点
        cal.set(Calendar.MINUTE, 0);//0分
        cal.set(Calendar.SECOND, 0);//0秒
        cal.set(Calendar.MILLISECOND, 0);//0毫秒
        return cal.getTime();
    }

    /**
     * 获取当天这个时间的小时数
     * @return
     */
    public static Date getDayEnd(){
        return Calendar.getInstance().getTime();
    }

    /**
     * 获取现在是今天的第多少哥小时
     * @return
     */
    public static int getDayOfCurrentHour(){
        DateTime now = new DateTime();
        int hour = now.hourOfDay().get();
        return hour;
    }


    /**
     * 获取几天是这个月的第几天
     *
     * @return
     */
    public static int getDayOfCurrentMonth(){
        DateTime now = new DateTime();
        return now.getDayOfMonth();
    }

    public static int getCurrentMonth(){
        DateTime now = new DateTime();
        return now.getMonthOfYear();
    }

    /**
     * 获取当前月是这个年的第多少哥月
     * @return
     */
    public static int getMonthOfCurrentYear(){
        DateTime now = new DateTime();
        return now.getMonthOfYear();
    }

    public static int getCurrentYear(){
        DateTime now = new DateTime();
        return now.getYear();
    }
    /**
     * 获取两个日期之间的天数
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return int 类型天数
     */
    public static int getTotalDaysOfTwoTime(DateTime  startTime,DateTime  endTime){
        return Days.daysBetween(startTime, endTime).getDays();
    }
    /**
     * 获取某个日期的开始时间
     * @param d
     * @return
     */
    public static Timestamp getDayStartTime(Date d) {
        Calendar calendar=Calendar.getInstance();
        if(null!=d){
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取本月的开始时间
     * @return
     */
    public static Date getBeginDayOfMonth() {
        Calendar calendar=Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth()-1, 1);

        return getDayStartTime(calendar.getTime());
    }



    /**
     * 获取本年的开始时间
     * @return
     */
    public static Date getBeginDayOfYear() {
        Calendar cal=Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.JANUARY);
        cal.set(Calendar.DATE, 1);

        return getDayStartTime(cal.getTime());
    }


    /**
     * 获取某个日期的结束时间
     * @param d
     * @return
     */
    public static Timestamp getDayEndTime(Date d) {
        Calendar calendar=Calendar.getInstance();
        if(null!=d){
            calendar.setTime(d);
        }
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH),
                calendar.get(Calendar.DAY_OF_MONTH), 23, 59, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new Timestamp(calendar.getTimeInMillis());
    }

    /**
     * 获取本月的结束时间
     * @return
     */
    public static Date getEndDayOfMonth() {
        Calendar calendar=Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth()-1, 1);
        int day = calendar.getActualMaximum(5);
        calendar.set(getNowYear(), getNowMonth()-1, day);
        calendar.set(Calendar.HOUR_OF_DAY, 23);//23点
        calendar.set(Calendar.MINUTE, 59);//59分
        calendar.set(Calendar.SECOND, 59);//59秒
        return getDayEndTime(calendar.getTime());
    }

    /**
     * 获取本年的结束时间
     * @return
     */
    public static Date getEndDayOfYear() {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, getNowYear());
        cal.set(Calendar.MONTH, Calendar.DECEMBER);
        cal.set(Calendar.DATE, 31);
        cal.set(Calendar.HOUR_OF_DAY, 23);//23点
        cal.set(Calendar.MINUTE, 59);//59分
        cal.set(Calendar.SECOND, 59);//59秒
        return getDayEndTime(cal.getTime());
    }

    /**
     * 获取今年是哪一年
     * @return
     */
    public static Integer getNowYear(){
        Date date = new Date();
        GregorianCalendar gc=(GregorianCalendar)Calendar.getInstance();
        gc.setTime(date);
        return Integer.valueOf(gc.get(1));
    }

    /**
     * 获取本月是哪一月
     * @return
     */
    public static int getNowMonth() {
        Date date = new Date();
        GregorianCalendar gc=(GregorianCalendar)Calendar.getInstance();
        gc.setTime(date);
        return gc.get(2) + 1;
    }

    /**
     * 获取本月往回偏移月份数后当月的开始日期
     * @param month 偏移的月份数
     * @return 本月往回偏移月份数后当月的开始日期
     */
    public static String getBeginDateOfMonth(int month) {
        month++;
        Calendar calendar=Calendar.getInstance();
        calendar.set(getNowYear(), getNowMonth()-month, 1);
        return DateUtil.format(calendar.getTime(), "yyyy-MM-dd");
    }

    /**
     * 将日期以天为单位偏移
     * @param date 日期
     * @param day 偏移的天数
     * @return 偏移后的日期
     */
    public static String offsetDay(String date, int day) {

        Date newDate = DateUtil.parse(date);
        Date newDate1 = DateUtil.offsetDay(newDate, day);
        return DateUtil.format(newDate1, "yyyy-MM-dd");
    }

    public static long getMinuteDiff(String startDate, String endDate) {

        Date newStartDate = DateUtil.parse(startDate);
        Date newEndDate = DateUtil.parse(endDate);
        return DateUtil.between(newStartDate, newEndDate, DateUnit.MINUTE);

    }

    public static String formatDateString(String date) {

        Date newDate = DateUtil.parse(date);
        return DateUtil.format(newDate, "yyyy-MM-dd");
    }

    /**
     * 根据年月获取这个月的天数
     * @param year
     * @param month
     * @return
     */
    public static int getDayNumberByMonth(int year, int month) {

        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month - 1);
        return cal.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 闰年的条件(满足之一即可):(1)能被4整除,但不能被100整除;(2)能被400整除
     * @param year
     * @param month
     * @return 返回天数
     */
    public static int getDays(int year, int month) {
        int days = 0;
        boolean isLeapYear = false;
        if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) {
            isLeapYear = true;
        } else {
            isLeapYear = false;
        }
        switch (month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                days = 31;
                break;
            case 2:
                if (isLeapYear) {
                    days = 29;
                } else {
                    days = 28;
                }
                break;
            case 4:
            case 6:
            case 9:
            case 11:
                days = 30;
                break;
            default:
                System.out.println("error!!!");
                break;
        }
        return days;
    }


    /**
     * 根据日期时间戳获取这一天的前 offsetDay 天的开始时间的时间戳(秒)
     * @param dateTimeMillis 日期时间戳(毫秒)
     * @param offsetDay 偏移天数(0为获取今天的)
     * @return 这一天的前 offsetDay 天的开始时间的时间戳(秒)
     */
    public static Long getBeginTimeMillisDay(Long dateTimeMillis, int offsetDay) {

        Date date = new Date(dateTimeMillis);
        //一天的开始
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1 * offsetDay);
        Date beginOfDay = DateUtil.beginOfDay(calendar.getTime());
        return beginOfDay.getTime() / 1000;
    }

    /**
     * 根据日期时间戳获取这一天的前 offsetDay 天的结束时间的时间戳(秒)
     * @param dateTimeMillis 日期时间戳(毫秒)
     * @param offsetDay 偏移天数(0为获取今天的)
     * @return 这一天的前 offsetDay 天的结束时间的时间戳(秒)
     */
    public static Long getEndTimeMillisDay(Long dateTimeMillis, int offsetDay) {

        Date date = new Date(dateTimeMillis);
        //一天的结束
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1 * offsetDay);
        Date endOfDay = DateUtil.endOfDay(calendar.getTime());
        return endOfDay.getTime() / 1000;
    }

    /**
     * 将日期以月份为单位偏移
     * @param date 日期
     * @param month 偏移的月份数
     * @return 偏移后的日期
     */
    public static String offsetMonth(String date, int month) {

        Date newDate = DateUtil.parse(date);
        //一天的开始
        Date beginOfDay = DateUtil.beginOfDay(newDate);
        Date newDate1 = DateUtil.offsetMonth(beginOfDay, month);
        return DateUtil.format(newDate1, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 根据日期时间戳获取这一月份的前 offsetMonth 月的开始时间的时间戳(秒)
     * @param dateTimeMillis 日期时间戳(毫秒)
     * @param offsetMonth 偏移月份数(0为获取本月的)
     * @return 这一天的前 offsetMonth 月的开始时间的时间戳(秒)
     */
    public static Long getBeginTimeMillisMonth(Long dateTimeMillis, int offsetMonth) {

        Date date = new Date(dateTimeMillis);
        //月的开始
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1 * offsetMonth);
        Date beginOfMonth = DateUtil.beginOfMonth(calendar.getTime());
        return beginOfMonth.getTime() / 1000;
    }

    /**
     * 根据日期时间戳获取这一月份的前 offsetMonth 月的结束时间的时间戳(秒)
     * @param dateTimeMillis 日期时间戳(毫秒)
     * @param offsetMonth 偏移月份数(0为获取本月的)
     * @return 这一天的前 offsetMonth 月的结束时间的时间戳(秒)
     */
    public static Long getEndTimeMillisMonth(Long dateTimeMillis, int offsetMonth) {

        Date date = new Date(dateTimeMillis);
        //月的结束
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1 * offsetMonth);
        Date endOfMonth = DateUtil.endOfMonth(calendar.getTime());
        return endOfMonth.getTime() / 1000;
    }

    /**
     * 获取时间戳相差多少天
     * @param beginTimeMillis 开始时间戳(秒)
     * @param endTimeMillis 结束时间戳(秒)
     * @return 时间戳相差多少天
     */
    public static long getDiffDay(Long beginTimeMillis, Long endTimeMillis) {

        Date beginDate = DateUtil.date(beginTimeMillis);
        Date endDate = DateUtil.date(endTimeMillis);
        return DateUtil.between(beginDate, endDate, DateUnit.DAY);
    }

    /**
     * 获取时间戳相差多少小时
     * @param beginTimeMillis 开始时间戳(毫秒)
     * @param endTimeMillis 结束时间戳(毫秒)
     * @return 时间戳相差多少天
     */
    public static long getDiffHour(Long beginTimeMillis, Long endTimeMillis) {

        Date beginDate = DateUtil.date(beginTimeMillis);
        Date endDate = DateUtil.date(endTimeMillis);
        return DateUtil.between(beginDate, endDate, DateUnit.HOUR);
    }

    /**
     * 时间戳格式成日期
     * @param dateTimeMillis 时间戳(毫秒)
     * @return
     */
    public static String formatTimeMillis(Long dateTimeMillis) {

        Date date = new Date(dateTimeMillis);
        return DateUtil.format(date, "yyyy-MM-dd");
    }



    public static DateTime parseDateTime(String dateTime){
        DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        return formatter.parseDateTime(dateTime);
    }

    /**
     * 获取指定日期的开始时间
     * @param date 指定日期
     * @return 指定日期的开始时间
     */
    public static String getBeginOfDay(String date) {

        Date newDate = DateUtil.parse(date);
        //一天的开始
        Date beginOfDay = DateUtil.beginOfDay(newDate);
        return DateUtil.format(beginOfDay, "yyyy-MM-dd HH:mm:ss");
    }

    public static String getEndOfDay(String date) {

        Date newDate = DateUtil.parse(date);
        //一天的结束
        Date endOfDay = DateUtil.endOfDay(newDate);
        return DateUtil.format(endOfDay, "yyyy-MM-dd HH:mm:ss");
    }


    Date date = new Date();
    int hours = date.getHours();

}
