• java8 日期操作


    package com.zxwa.ntmss.process.common.util.date;
    
    import java.time.*;
    import java.time.format.DateTimeFormatter;
    import java.time.format.DateTimeParseException;
    import java.time.format.FormatStyle;
    import java.time.format.ResolverStyle;
    import java.time.temporal.ChronoUnit;
    import java.time.temporal.Temporal;
    import java.time.temporal.TemporalAdjusters;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    import com.google.common.collect.Lists;
    import com.google.protobuf.ServiceException;
    import org.apache.commons.lang.ObjectUtils;
    
    /**
     * java1.8 的新特性,解决SimpleDateFormat的线程问题<br>
     * <li>Instant代替 Date,</li>
     * <li>LocalDateTime代替 Calendar,</li>
     * <li>DateTimeFormatter 代替 SimpleDateFormat.</li> 注意:如果是共享变量,则可能会出现线程问题。<br>
     *
     * @author zero 2019/03/30
     */
    public class DateUtil8 {
        /**
         * getYear()    int    获取当前日期的年份
         * getMonth()    Month    获取当前日期的月份对象
         * getMonthValue()    int    获取当前日期是第几月
         * getDayOfWeek()    DayOfWeek    表示该对象表示的日期是星期几
         * getDayOfMonth()    int    表示该对象表示的日期是这个月第几天
         * getDayOfYear()    int    表示该对象表示的日期是今年第几天
         * withYear(int year)    LocalDate    修改当前对象的年份
         * withMonth(int month)    LocalDate    修改当前对象的月份
         * withDayOfMonth(int dayOfMonth)    LocalDate    修改当前对象在当月的日期
         * isLeapYear()    boolean    是否是闰年
         * lengthOfMonth()    int    这个月有多少天
         * lengthOfYear()    int    该对象表示的年份有多少天(365或者366)
         * plusYears(long yearsToAdd)    LocalDate    当前对象增加指定的年份数
         * plusMonths(long monthsToAdd)    LocalDate    当前对象增加指定的月份数
         * plusWeeks(long weeksToAdd)    LocalDate    当前对象增加指定的周数
         * plusDays(long daysToAdd)    LocalDate    当前对象增加指定的天数
         * minusYears(long yearsToSubtract)    LocalDate    当前对象减去指定的年数
         * minusMonths(long monthsToSubtract)    LocalDate    当前对象减去注定的月数
         * minusWeeks(long weeksToSubtract)    LocalDate    当前对象减去指定的周数
         * minusDays(long daysToSubtract)    LocalDate    当前对象减去指定的天数
         * compareTo(ChronoLocalDate other)    int    比较当前对象和other对象在时间上的大小,返回值如果为正,则当前对象时间较晚,
         * isBefore(ChronoLocalDate other)    boolean    比较当前对象日期是否在other对象日期之前
         * isAfter(ChronoLocalDate other)    boolean    比较当前对象日期是否在other对象日期之后
         * isEqual(ChronoLocalDate other)    boolean    比较两个日期对象是否相等
         */
    
    
        // 时间元素
        private static final String YEAR = "year";
        private static final String MONTH = "month";
        private static final String WEEK = "week";
        private static final String DAY = "day";
        private static final String HOUR = "hour";
        private static final String MINUTE = "minute";
        private static final String SECOND = "second";
    
        // 星期元素
        private static final String MONDAY = "MONDAY";// 星期一
        private static final String TUESDAY = "TUESDAY";// 星期二
        private static final String WEDNESDAY = "WEDNESDAY";// 星期三
        private static final String THURSDAY = "THURSDAY";// 星期四
        private static final String FRIDAY = "FRIDAY";// 星期五
        private static final String SATURDAY = "SATURDAY";// 星期六
        private static final String SUNDAY = "SUNDAY";// 星期日
    
    
        private static final String YYYY_MM = "yyyy-MM";
        private static final String YYYY_MM_DD = "yyyy-MM-dd";
        private static final String YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
        private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
        private static final String YYYY_MM_DD_HH_MM_00 = "yyyy-MM-dd HH:mm:00";
        private static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyy-MM-dd HH:mm:ss SSS";
    
        private static final String YYYY_MM_EN = "yyyy/MM";
        private static final String YYYY_MM_DD_EN = "yyyy/MM/dd";
        private static final String YYYY_MM_DD_HH_MM_EN = "yyyy/MM/dd HH:mm";
        private static final String YYYY_MM_DD_HH_MM_SS_EN = "yyyy/MM/dd HH:mm:ss";
        private static final String YYYY_MM_CN = "yyyy年MM月";
        private static final String YYYY_MM_DD_CN = "yyyy年MM月dd日";
        private static final String YYYY_MM_DD_HH_MM_CN = "yyyy年MM月dd日 HH:mm";
        private static final String YYYY_MM_DD_HH_MM_SS_CN = "yyyy年MM月dd日 HH:mm:ss";
        private static final String YYYY_MM_DD_CN2 = "yyyy.MM.dd";
    
        private static final String YYYY = "yyyy";
        private static final String YYYYMM = "yyyyMM";
        private static final String YYYYMMDD = "yyyyMMdd";
        private static final String YYYYMMDDHH = "yyyyMMddHH";
        private static final String YYYYMMDDHHMM = "yyyyMMddHHmm";
        private static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    
        private static final String HH_MM = "HH:mm";
        private static final String HH_MM_SS = "HH:mm:ss";
    
        private static final String MM_DD = "MM-dd";
        private static final String MM_DD_HH_MM = "MM-dd HH:mm";
        private static final String MM_DD_HH_MM_SS = "MM-dd HH:mm:ss";
    
        private static final String MM_DD_EN = "MM/dd";
        private static final String MM_DD_HH_MM_EN = "MM/dd HH:mm";
        private static final String MM_DD_HH_MM_SS_EN = "MM/dd HH:mm:ss";
    
        private static final String MM_DD_CN = "MM月dd日";
        private static final String MM_DD_HH_MM_CN = "MM月dd日 HH:mm";
        private static final String MM_DD_HH_MM_SS_CN = "MM月dd日 HH:mm:ss";
    
    
        // 本地时间显示格式:区分中文和外文显示
        private static final DateTimeFormatter shotDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
        private static final DateTimeFormatter fullDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
        private static final DateTimeFormatter longDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
        private static final DateTimeFormatter mediumDate = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
    
    
        /**
         * 简写本地当前日期:yy-M-dd<br>
         * 例如:19-3-30为2019年3月30日
         *
         * @return 字符串yy-M-dd
         * @author zero 2019/03/30
         */
        public static String getNowLocalTime_shot() {
            return LocalDateTime.now().format(shotDate);
        }
    
        /**
         * 根据当地日期显示格式:yyyy年M月dd日 星期?(中国)
         *
         * @return 形如:2019年3月30日 星期六
         * @author zero 2019/03/30
         */
        public static String getNowLocalTime_full() {
            return LocalDateTime.now().format(fullDate);
        }
    
        /**
         * 根据当地显示日期格式:yyyy年M月dd日(中国)
         *
         * @return 形如 2019年3月30日
         * @author zero 2019/03/30
         */
        public static String getNowLocalTime_long() {
            return LocalDateTime.now().format(longDate);
        }
    
        /**
         * 根据当地显示日期格式:yyyy-M-dd(中国)
         *
         * @return 形如:2019-3-30
         * @author zero 2019/03/30
         */
        public static String getNowLocalTime_medium() {
            return LocalDateTime.now().format(mediumDate);
        }
    
        /**
         * 获取当前日期
         *
         * @return 字符串yyyy-MM-dd HH:mm:ss
         * @author zero 2019/03/30
         */
        public static String getNowTime(String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return LocalDateTime.now().format(formatter);
        }
    
        /**
         * 获取当前日期的节点时间(年,月,周,日,时,分,秒)
         *
         * @param node 日期中的节点元素(年,月,周,日,时,分,秒)
         * @return 节点数字,如创建此方法的时间:年 2019,月 3,日 30,周 6
         * @author zero 2019/03/30 星期六
         */
        public static Integer getNodeTime(String node) {
            LocalDateTime today = LocalDateTime.now();
            Integer resultNode = null;
            switch (node) {
                case YEAR:
                    resultNode = today.getYear();
                    break;
                case MONTH:
                    resultNode = today.getMonthValue();
                    break;
                case WEEK:
                    resultNode = transformWeekEN2Num(String.valueOf(today.getDayOfWeek()));
                    break;
                case DAY:
                    resultNode = today.getDayOfMonth();
                    break;
                case HOUR:
                    resultNode = today.getHour();
                    break;
                case MINUTE:
                    resultNode = today.getMinute();
                    break;
                case SECOND:
                    resultNode = today.getSecond();
                    break;
                default:
                    // 当前日期是当前年的第几天。例如:2019/1/3是2019年的第三天
                    resultNode = today.getDayOfYear();
                    break;
            }
            return resultNode;
        }
    
        /**
         * 将英文星期转换成数字
         *
         * @param enWeek 英文星期
         * @return int,如果数字小于0,则检查,看是否输入错误 or 入参为null
         * @author zero 2019/03/30
         */
        public static int transformWeekEN2Num(String enWeek) {
            if (MONDAY.equals(enWeek)) {
                return 1;
            } else if (TUESDAY.equals(enWeek)) {
                return 2;
            } else if (WEDNESDAY.equals(enWeek)) {
                return 3;
            } else if (THURSDAY.equals(enWeek)) {
                return 4;
            } else if (FRIDAY.equals(enWeek)) {
                return 5;
            } else if (SATURDAY.equals(enWeek)) {
                return 6;
            } else if (SUNDAY.equals(enWeek)) {
                return 7;
            } else {
                return -1;
            }
        }
    
        /**
         * 获取当前日期之后(之后)的节点事件<br>
         * <ul>
         * 比如当前时间为:2019-03-30 10:20:30
         * </ul>
         * <li>node="hour",num=5L:2019-03-30 15:20:30</li>
         * <li>node="day",num=1L:2019-03-31 10:20:30</li>
         * <li>node="year",num=1L:2020-03-30 10:20:30</li>
         *
         * @param node 节点元素(“year”,"month","week","day","huor","minute","second")
         * @param num  第几天(+:之后,-:之前)
         * @return 之后或之后的日期
         * @author zero 2019/03/30
         */
        public static String getAfterOrPreNowTime(String node, Long num, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            LocalDateTime now = LocalDateTime.now();
            if (HOUR.equals(node)) {
                return now.plusHours(num).format(formatter);
            } else if (DAY.equals(node)) {
                return now.plusDays(num).format(formatter);
            } else if (WEEK.equals(node)) {
                return now.plusWeeks(num).format(formatter);
            } else if (MONTH.equals(node)) {
                return now.plusMonths(num).format(formatter);
            } else if (YEAR.equals(node)) {
                return now.plusYears(num).format(formatter);
            } else if (MINUTE.equals(node)) {
                return now.plusMinutes(num).format(formatter);
            } else if (SECOND.equals(node)) {
                return now.plusSeconds(num).format(formatter);
            } else {
                return "Node is Error!";
            }
        }
    
        /**
         * 获取与当前日期相距num个之后(之前)的日期<br>
         * <ul>
         * 比如当前时间为:2019-03-30 10:20:30的格式日期
         * <li>node="hour",num=5L:2019-03-30 15:20:30</li>
         * <li>node="day",num=1L:2019-03-31 10:20:30</li>
         * <li>node="year",num=1L:2020-03-30 10:20:30</li>
         * </ul>
         *
         * @param style(dtf = yyyyMMddHHmmss_EN)
         * @param node      节点元素(“year”,"month","week","day","huor","minute","second")
         * @param num       (+:之后,-:之前)
         * @return 之后之前的日期
         * @author zero 2019/03/30
         */
        public static String getAfterOrPreNowTimePlus(String node, Long num, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            LocalDateTime now = LocalDateTime.now();
            if (HOUR.equals(node)) {
                return now.plusHours(num).format(formatter);
            } else if (DAY.equals(node)) {
                return now.plusDays(num).format(formatter);
            } else if (WEEK.equals(node)) {
                return now.plusWeeks(num).format(formatter);
            } else if (MONTH.equals(node)) {
                return now.plusMonths(num).format(formatter);
            } else if (YEAR.equals(node)) {
                return now.plusYears(num).format(formatter);
            } else if (MINUTE.equals(node)) {
                return now.plusMinutes(num).format(formatter);
            } else if (SECOND.equals(node)) {
                return now.plusSeconds(num).format(formatter);
            } else {
                return "Node is Error!";
            }
        }
    
        /**
         * 当前时间的hour,minute,second之后(之前)的时刻
         *
         * @param node 时间节点元素(hour,minute,second)
         * @param num  之后(之后)多久时,分,秒(+:之后,-:之前)
         * @return HH:mm:ss 字符串
         * @author zero 2019/03/30
         */
        public static String getAfterOrPreNowTimeSimp(String node, Long num, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            LocalTime now = LocalTime.now();
            if (HOUR.equals(node)) {
                return now.plusHours(num).format(formatter);
            } else if (MINUTE.equals(node)) {
                return now.plusMinutes(num).format(formatter);
            } else if (SECOND.equals(node)) {
                return now.plusSeconds(num).format(formatter);
            } else {
                return "Node is Error!";
            }
        }
    
        /**
         * 检查重复事件,比如生日。TODO This is a example.
         *
         * @param month 1 2 3 . . .
         * @return
         * @author zero 2019/03/31
         */
        public static boolean isBirthday(int month, int dayOfMonth) {
            MonthDay birthDay = MonthDay.of(month, dayOfMonth);
            MonthDay curMonthDay = MonthDay.from(LocalDate.now());// MonthDay只存储了月、日。
            if (birthDay.equals(curMonthDay)) {
                return true;
            }
            return false;
        }
    
        /**
         * 获取当前日期第index日之后(之前)的日期(yyyy-MM-dd)
         *
         * @param index 第index天
         * @return 日期字符串:yyyy-MM-dd
         * @author zero 2019/03/31
         */
        public static String getAfterOrPreDayDate(int index, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return LocalDate.now().plus(index, ChronoUnit.DAYS).format(formatter);
        }
    
        /**
         * 获取当前日期第index周之前(之后)的日期(yyyy-MM-dd)
         *
         * @param index 第index周(+:之后,-:之前)
         * @return 日期字符串:yyyy-MM-dd
         * @author zero 2019/03/31
         */
        public static String getAfterOrPreWeekDate(int index, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return LocalDate.now().plus(index, ChronoUnit.WEEKS).format(formatter);
        }
    
        /**
         * 获取当前日期第index月之前(之后)的日期(yyyy-MM-dd)
         *
         * @param index 第index月(+:之后,-:之前)
         * @return 日期字符串:yyyy-MM-dd
         * @author zero 2019/03/31
         */
        public static String getAfterOrPreMonthDate(int index, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return LocalDate.now().plus(index, ChronoUnit.MONTHS).format(formatter);
        }
    
        /**
         * 获取当前日期第index年之前(之后)的日期(yyyy-MM-dd)
         *
         * @param index 第index年(+:之后,-:之前)
         * @return 日期字符串:yyyy-MM-dd
         * @author zero 2019/03/31
         */
        public static String getAfterOrPreYearDate(int index, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return LocalDate.now().plus(index, ChronoUnit.YEARS).format(formatter);
        }
    
        /**
         * 获取指定日期之前之后的第index的日,周,月,年的日期
         *
         * @param date  指定日期格式:yyyy-MM-dd
         * @param node  时间节点元素(日周月年)
         * @param index 之前之后第index个日期
         * @return yyyy-MM-dd 日期字符串
         * @author zero 2019/03/31
         */
        public static String getAfterOrPreDate(String date, String node, int index, String style) {
            date = date.trim();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            if (DAY.equals(node)) {
                return LocalDate.parse(date).plus(index, ChronoUnit.DAYS).format(formatter);
            } else if (WEEK.equals(node)) {
                return LocalDate.parse(date).plus(index, ChronoUnit.WEEKS).format(formatter);
            } else if (MONTH.equals(node)) {
                return LocalDate.parse(date).plus(index, ChronoUnit.MONTHS).format(formatter);
            } else if (YEAR.equals(node)) {
                return LocalDate.parse(date).plus(index, ChronoUnit.YEARS).format(formatter);
            } else {
                return "Wrong date format!";
            }
        }
    
        /**
         * 检测:输入年份是否是闰年?
         *
         * @param date 日期格式:yyyy-MM-dd
         * @return true:闰年,false:平年
         * @author zero 2019/03/31
         */
        public static boolean isLeapYear(String date) {
            return LocalDate.parse(date.trim()).isLeapYear();
        }
    
        /**
         * 计算两个日期字符串之间相差多少个周期(天,月,年)
         *
         * @param date1 yyyy-MM-dd
         * @param date2 yyyy-MM-dd
         * @param node  三者之一:(day,month,year)
         * @return 相差多少周期
         * @author zero 2019/03/31
         */
        public static int peridCount(String date1, String date2, String node) {
            date1 = date1.trim();
            date2 = date2.trim();
            if (DAY.equals(node)) {
                return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getDays();
            } else if (MONTH.equals(node)) {
                return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getMonths();
            } else if (YEAR.equals(node)) {
                return Period.between(LocalDate.parse(date1), LocalDate.parse(date2)).getYears();
            } else {
                return 0;
            }
        }
    
        /**
         * 切割日期。按照周期切割成小段日期段。例如: <br>
         *
         * @param startDate 开始日期(yyyy-MM-dd)
         * @param endDate   结束日期(yyyy-MM-dd)
         * @param period    周期(天,周,月,年)
         * @return 切割之后的日期集合
         * @author zero 2019/04/02
         * @example <li>startDate="2019-02-28",endDate="2019-03-05",period="day"</li>
         * <li>结果为:[2019-02-28, 2019-03-01, 2019-03-02, 2019-03-03, 2019-03-04, 2019-03-05]</li><br>
         * <li>startDate="2019-02-28",endDate="2019-03-25",period="week"</li>
         * <li>结果为:[2019-02-28,2019-03-06, 2019-03-07,2019-03-13, 2019-03-14,2019-03-20,
         * 2019-03-21,2019-03-25]</li><br>
         * <li>startDate="2019-02-28",endDate="2019-05-25",period="month"</li>
         * <li>结果为:[2019-02-28,2019-02-28, 2019-03-01,2019-03-31, 2019-04-01,2019-04-30,
         * 2019-05-01,2019-05-25]</li><br>
         * <li>startDate="2019-02-28",endDate="2020-05-25",period="year"</li>
         * <li>结果为:[2019-02-28,2019-12-31, 2020-01-01,2020-05-25]</li><br>
         */
        public static List<String> getPieDateRange(String startDate, String endDate, String style, String period) {
            List<String> result = Lists.newArrayList();
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(style);
            LocalDate end = LocalDate.parse(endDate, dateTimeFormatter);
            LocalDate start = LocalDate.parse(startDate, dateTimeFormatter);
            LocalDate tmp = start;
            switch (period) {
                case DAY:
                    while (start.isBefore(end) || start.isEqual(end)) {
                        result.add(start.toString());
                        start = start.plusDays(1);
                    }
                    break;
                case WEEK:
                    while (tmp.isBefore(end) || tmp.isEqual(end)) {
                        if (tmp.plusDays(6).isAfter(end)) {
                            result.add(tmp.toString() + "," + end);
                        } else {
                            result.add(tmp.toString() + "," + tmp.plusDays(6));
                        }
                        tmp = tmp.plusDays(7);
                    }
                    break;
                case MONTH:
                    while (tmp.isBefore(end) || tmp.isEqual(end)) {
                        LocalDate lastDayOfMonth = tmp.with(TemporalAdjusters.lastDayOfMonth());
                        if (lastDayOfMonth.isAfter(end)) {
                            result.add(tmp.toString() + "," + end);
                        } else {
                            result.add(tmp.toString() + "," + lastDayOfMonth);
                        }
                        tmp = lastDayOfMonth.plusDays(1);
                    }
                    break;
                case YEAR:
                    while (tmp.isBefore(end) || tmp.isEqual(end)) {
                        LocalDate lastDayOfYear = tmp.with(TemporalAdjusters.lastDayOfYear());
                        if (lastDayOfYear.isAfter(end)) {
                            result.add(tmp.toString() + "," + end);
                        } else {
                            result.add(tmp.toString() + "," + lastDayOfYear);
                        }
                        tmp = lastDayOfYear.plusDays(1);
                    }
                    break;
                default:
                    break;
            }
            return result;
        }
    
        /**
         * 指定日期月的最后一天(yyyy-MM-dd)
         *
         * @param curDate     日期格式(yyyy-MM-dd)
         * @param firstOrLast true:第一天,false:最后一天
         * @return
         * @author zero 2019/04/13
         */
        public static String getLastDayOfMonth(String curDate, String style, boolean firstOrLast) {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(style);
            if (firstOrLast) {
                return LocalDate.parse(curDate, dateTimeFormatter).with(TemporalAdjusters.firstDayOfMonth()).toString();
            } else {
                return LocalDate.parse(curDate, dateTimeFormatter).with(TemporalAdjusters.lastDayOfMonth()).toString();
            }
        }
    
        /**
         * 指定日期年的最后一天(yyyy-MM-dd)
         *
         * @param curDate     指定日期(格式:yyyy-MM-dd)
         * @param firstOrLast true:第一天,false:最后一天
         * @return
         * @author zero 2019/04/13
         */
        public static String getLastDayOfYear(String curDate, String style, boolean firstOrLast) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            if (firstOrLast) {
                return LocalDate.parse(curDate, formatter).with(TemporalAdjusters.firstDayOfYear()).toString();
            } else {
                return LocalDate.parse(curDate, formatter).with(TemporalAdjusters.lastDayOfYear()).toString();
            }
        }
    
        /**
         * 获取下一个星期的日期
         *
         * @param curDay          yyyy-MM-dd
         * @param dayOfWeek       monday:1~sunday:7
         * @param isContainCurDay 是否包含当天,true:是,false:不包含
         * @return 日期(yyyy-MM-dd)
         * @author zero 2019/04/02
         */
        public static String getNextWeekDate(String curDay, int dayOfWeek, boolean isContainCurDay) {
            dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek;
            if (isContainCurDay) {
                return LocalDate.parse(curDay).with(TemporalAdjusters.nextOrSame(DayOfWeek.of(dayOfWeek))).toString();
            } else {
                return LocalDate.parse(curDay).with(TemporalAdjusters.next(DayOfWeek.of(dayOfWeek))).toString();
            }
        }
    
        /**
         * 获取上一个星期的日期
         *
         * @param curDay    指定日期(yyyy-MM-dd)
         * @param dayOfWeek 数字范围(monday:1~sunday:7)
         * @param isCurDay  是否包含当天,true:是,false:不包含
         * @return 日期(yyyy-MM-dd)
         * @author zero 2019/04/02
         */
        public static String getPreWeekDate(String curDay, int dayOfWeek, boolean isCurDay) {
            dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek;
            if (isCurDay) {
                return LocalDate.parse(curDay).with(TemporalAdjusters.previousOrSame(DayOfWeek.of(dayOfWeek))).toString();
            } else {
                return LocalDate.parse(curDay).with(TemporalAdjusters.previous(DayOfWeek.of(dayOfWeek))).toString();
            }
        }
    
        /**
         * 获取指定日期当月的最后或第一个星期日期
         *
         * @param curDay      指定日期(yyyy-MM-dd)
         * @param dayOfWeek   周几(1~7)
         * @param lastOrFirst true:最后一个,false本月第一个
         * @return 日期(yyyy-MM-dd)
         * @author zero 2019/04/02
         */
        public static String getFirstOrLastWeekDate(String curDay, int dayOfWeek, boolean lastOrFirst) {
            dayOfWeek = dayOfWeek < 1 || dayOfWeek > 7 ? 1 : dayOfWeek;
            if (lastOrFirst) {
                return LocalDate.parse(curDay).with(TemporalAdjusters.lastInMonth(DayOfWeek.of(dayOfWeek))).toString();
            } else {
                return LocalDate.parse(curDay).with(TemporalAdjusters.firstInMonth(DayOfWeek.of(dayOfWeek))).toString();
            }
        }
    
        /**************************************************豪华分割线****************************************************************/
    
        /**
         * 获得当前时间戳 精确到毫秒
         *
         * @return
         */
        public static long get2EpochMilli() {
            return Instant.now().toEpochMilli();
        }
    
        /**
         * 获得当前时间戳 精确到秒
         *
         * @return
         */
        public static long getEpochSecond() {
            return Instant.now().getEpochSecond();
        }
    
        /**
         * instantTime 时间戳   dtf 格式风格
         * 将Long类型的毫秒时间戳转换成String 类型的时间格式
         */
        public static String InstantTimeToString(Long instantTime, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return formatter.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(instantTime), ZoneId.systemDefault()));
        }
    
    
        /**
         * time 和 dtf的格式化风格要对应
         * 将字符串转日期成Long类型的毫秒时间戳
         */
        public static Long timeToLong(String time, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            LocalDateTime parse = LocalDateTime.parse(time, formatter);
            return LocalDateTime.from(parse).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        }
    
    
        /**
         * 将Long类型的时间戳转换成String 类型的时间格式,时间格式为:yyyy-MM-dd HH:mm:ss
         */
        public static String timeToString(Long time, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return formatter.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()));
        }
    
    
        /**
         * 取本月第一天
         */
        public static LocalDate firstDayOfThisMonth() {
            LocalDate today = LocalDate.now();
            return today.with(TemporalAdjusters.firstDayOfMonth());
        }
    
        /**
         * 取本月第一天
         */
        public static LocalDate firstDayOfLastMonth() {
            LocalDate today = LocalDate.now();
            today = today.minusMonths(1);
            return today.with(TemporalAdjusters.firstDayOfMonth());
        }
    
        /**
         * 取本月第N天
         */
        public static LocalDate dayOfThisMonth(int n) {
            LocalDate today = LocalDate.now();
            return today.withDayOfMonth(n);
        }
    
        /**
         * 取本月最后一天
         */
        public static LocalDate lastDayOfThisMonth() {
            LocalDate today = LocalDate.now();
            return today.with(TemporalAdjusters.lastDayOfMonth());
        }
    
        /**
         * 获取本周一
         */
        public static LocalDateTime firstDayOfWeek(Long date) {
            // long转LocalDateTime
            LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date), ZoneId.systemDefault());
            return localDateTime.with(DayOfWeek.MONDAY);
        }
    
        /**
         * 获取上周一
         */
        public static LocalDateTime firstDayOfLastWeek(Long date) {
            // long转LocalDateTime
            LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date), ZoneId.systemDefault());
            LocalDateTime localDateTime1 = localDateTime.plusDays(-7);
            return localDateTime1.with(DayOfWeek.MONDAY);
        }
    
        /**
         * 获取上周一
         */
        public static LocalDateTime lastDay(Long date) {
            // long转LocalDateTime
            LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochSecond(date), ZoneId.systemDefault());
            LocalDateTime localDateTime1 = localDateTime.plusDays(-1);
            return localDateTime1;
        }
    
        /**
         * 取本月第一天的开始时间
         */
        public static LocalDateTime startOfThisMonth() {
            return LocalDateTime.of(firstDayOfThisMonth(), LocalTime.MIN);
        }
    
        /**
         * 取本月最后一天的结束时间
         */
        public static LocalDateTime endOfThisMonth() {
            return LocalDateTime.of(lastDayOfThisMonth(), LocalTime.MAX);
        }
    
    
        /**
         * 判断某个字符串是否是指定的时间格式
         *
         * @param strTime 字符串时间
         */
    
        public static boolean verifyDate(String strTime, String style) {
            DateTimeFormatter ldt = DateTimeFormatter.ofPattern(style.replace("y", "u")).withResolverStyle(ResolverStyle.STRICT);
            boolean dateFlag = true;
            try {
                LocalDate.parse(strTime, ldt);
            } catch (DateTimeParseException | NullPointerException e) {
                dateFlag = false;
            }
            return dateFlag;
        }
    
        /**
         * java8 获取两个日期间的所有日期
         *
         * @param start yyyy-mm-dd
         * @param end   yyyy-mm-dd
         * @return
         */
        public static List<String> getBetweenDate(String start, String end) {
            List<String> list = new ArrayList<>();
            LocalDate startDate = null;
            LocalDate endDate = null;
            try {
                startDate = LocalDate.parse(start);
                endDate = LocalDate.parse(end);
            } catch (Exception e) {
                throw new RuntimeException("日期格式不正确。(日期示例:2019-12-26)");
            }
            long numOfDays = ChronoUnit.DAYS.between(startDate, endDate);
            List<LocalDate> listOfDates1 = Stream
                    .iterate(startDate, date -> date.plusMonths(1))
                    .limit(numOfDays)
                    .collect(Collectors.toList());
    
            listOfDates1.forEach(item -> {
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-mm-dd");
                String format = dateTimeFormatter.format(item);
                list.add(format);
            });
            return list;
        }
    
    
        /**
         * java8 获取两个日期间的所有月份
         *
         * @param start yyyy-mm-dd
         * @param end   yyyy-mm-dd
         * @return
         */
        public static List<String> getBetweenMonth(String start, String end) {
            List<String> list = new ArrayList<>();
            LocalDate startDate = null;
            LocalDate endDate = null;
            try {
                startDate = LocalDate.parse(start);
                endDate = LocalDate.parse(end);
            } catch (Exception e) {
                throw new RuntimeException("日期格式不正确。(日期示例:2019-12-26)");
            }
            long numOfDays = ChronoUnit.MONTHS.between(startDate, endDate);
            List<LocalDate> listOfDates1 = Stream
                    .iterate(startDate, date -> date.plusMonths(1))
                    .limit(numOfDays)
                    .collect(Collectors.toList());
    
            listOfDates1.forEach(item -> {
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
                String format = dateTimeFormatter.format(item);
                list.add(format);
            });
            return list;
        }
    
    
        /**
         * java8 获取两个日期间的所有年份
         *
         * @param start yyyy-mm-dd
         * @param end   yyyy-mm-dd
         * @return
         */
        public static List<String> getBetweenYear(String start, String end) {
            List<String> list = new ArrayList<>();
            LocalDate startDate = null;
            LocalDate endDate = null;
            try {
                startDate = LocalDate.parse(start);
                endDate = LocalDate.parse(end);
            } catch (Exception e) {
                throw new RuntimeException("日期格式不正确。(日期示例:2019-12-26)");
            }
            long numOfDays = ChronoUnit.YEARS.between(startDate, endDate);
            List<LocalDate> listOfDates1 = Stream
                    .iterate(startDate, date -> date.plusYears(1))
                    .limit(numOfDays)
                    .collect(Collectors.toList());
    
            listOfDates1.forEach(item -> {
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy");
                String format = dateTimeFormatter.format(item);
                list.add(format);
            });
            return list;
        }
    
    
        /**
         * 返回当前的日期
         *
         * @return
         */
        public static LocalDate getCurrentLocalDate() {
            return LocalDate.now();
        }
    
        /**
         * 返回当前日期时间
         *
         * @return
         */
        public static LocalDateTime getCurrentLocalDateTime() {
            return LocalDateTime.now();
        }
    
    
        /**
         * @param dateStr yyyy-mm-dd
         * @param pattern
         * @return
         */
        public static LocalDate parseLocalDate(String dateStr, String pattern) {
            return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
        }
    
        /**
         * 带有时间的格式
         *
         * @param dateTimeStr yyyy-mm-dd
         * @param pattern
         * @return
         */
        public static LocalDateTime parseLocalDateTime(String dateTimeStr, String pattern) {
            return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
        }
    
    
        /**
         * 日期相隔天数
         *
         * @param startDateInclusive
         * @param endDateExclusive
         * @return
         */
        public static int periodDays(LocalDate startDateInclusive, LocalDate endDateExclusive) {
            return Period.between(startDateInclusive, endDateExclusive).getDays();
        }
    
        /**
         * 日期相隔小时
         *
         * @param startInclusive
         * @param endExclusive
         * @return
         */
        public static long durationHours(Temporal startInclusive, Temporal endExclusive) {
            return Duration.between(startInclusive, endExclusive).toHours();
        }
    
        /**
         * 日期相隔分钟
         *
         * @param startInclusive
         * @param endExclusive
         * @return
         */
        public static long durationMinutes(Temporal startInclusive, Temporal endExclusive) {
            return Duration.between(startInclusive, endExclusive).toMinutes();
        }
    
        /**
         * 日期相隔毫秒数
         *
         * @param startInclusive
         * @param endExclusive
         * @return
         */
        public static long durationMillis(Temporal startInclusive, Temporal endExclusive) {
            return Duration.between(startInclusive, endExclusive).toMillis();
        }
    
        /**
         * 是否当天
         *
         * @param date
         * @return
         */
        public static boolean isToday(LocalDate date) {
            return getCurrentLocalDate().equals(date);
        }
    
        /**
         * 获取本月的第一天
         *
         * @return
         */
        public static String getFirstDayOfThisMonth(DateTimeFormatter dtf) {
            return getCurrentLocalDate().with(TemporalAdjusters.firstDayOfMonth()).format(dtf);
        }
    
        /**
         * 获取本月的最后一天
         * 注  只能是日期不能带有时间
         *
         * @return
         */
        public static String getLastDayOfThisMonth(DateTimeFormatter dtf) {
            return getCurrentLocalDate().with(TemporalAdjusters.lastDayOfMonth()).format(dtf);
        }
    
        /**
         * 获取2017-01的第一个周一
         * 注  只能是日期不能带有时间
         *
         * @return
         */
        public static String getFirstMonday(String strDate, DateTimeFormatter dtf) {
            return LocalDate.parse(strDate).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)).format(dtf);
        }
    
        /**
         * 获取当前日期的后两周
         * 注  只能是日期不能带有时间
         *
         * @return
         */
        public static String getCurDateAfterTwoWeek(long num, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return getCurrentLocalDate().plus(num, ChronoUnit.WEEKS).format(formatter);
        }
    
        /**
         * 获取当前日期的6个月后的日期
         *
         * @return
         */
        public static String getCurDateAfterNumMonth(long num, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return getCurrentLocalDate().plus(num, ChronoUnit.MONTHS).format(formatter);
        }
    
        /**
         * 获取当前日期的5年后的日期
         * 注:只能是日期 不能包含时间
         *
         * @return
         */
        public static String getCurDateAfterFiveYear(long num, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return getCurrentLocalDate().plus(num, ChronoUnit.YEARS).format(formatter);
        }
    
        /**
         * 获取当前日期的20年后的日期
         * <p>
         * 注:只能是日期 不能包含时间
         *
         * @return
         */
        public static String getCurDateAfterTwentyYear(long num, String style) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(style);
            return getCurrentLocalDate().plus(num, ChronoUnit.DECADES).format(formatter);
        }
    
        //==================================================================================时间戳相关
    
        /**
         * LocalDate转时间戳 到秒
         */
        public static Long localDate2Second(LocalDate localDate) {
            return LocalDateTime.of(localDate, LocalTime.MIN).toInstant(ZoneOffset.ofHours(8)).getEpochSecond();
        }
    
        /**
         * LocalDateTime转时间戳 到秒
         */
        public static Long localDateTime2Second(LocalDateTime localDateTime) {
            return localDateTime.toEpochSecond(ZoneOffset.of("+8"));
        }
    
    
        /**
         * LocalDateTime转时间戳 毫秒
         */
        public static Long localDateTime2Milli(String dateTime, String style) {
            LocalDateTime parse = LocalDateTime.parse(dateTime, DateTimeFormatter.ofPattern(style));
            return LocalDateTime.from(parse).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        }
    
    
        /**
         * 获取当前时间毫秒值
         *
         * @return
         */
        public static long getCurrentMilli() {
            return Instant.now().toEpochMilli();
        }
    
    
        /**
         * 获取当前时间毫秒值
         *
         * @return
         */
        public static long getCurrentSecond() {
            return Instant.now().getEpochSecond();
        }
    
    
        // DateUtil8
    
        public static void main(String[] args) {
            boolean b = verifyDate("20201629110907", DateUtil8.YYYYMMDDHHMMSS);
    
            System.out.println(b);
        }
    }
    故乡明
  • 相关阅读:
    自主问题--KMP算法
    题解--luogu--CSP2019.S.Day2.T4--Emiya 家今天的饭
    浅谈——RMQ
    浅谈——LCA
    NOIP(si le)或者CSP初赛之——前序中序后序,前缀中缀后缀
    浅说——查分约束
    浅说——tarjan
    C++ RQNOJ 星门龙跃
    C++ 洛谷 1261:【例9.5】城市交通路网
    刷题
  • 原文地址:https://www.cnblogs.com/luweiweicode/p/14070587.html
Copyright © 2020-2023  润新知