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); } }