点击查看
import org.junit.Test;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.time.temporal.WeekFields;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Java8DateUtil {
public static final String yyyy_MM_dd_HH_mm_ss_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
public static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
public static final String yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";
public static final String yyyy_MM_dd_HH_mm_ss_cn = "yyyy年MM月dd日 HH时mm分ss秒";
public static final String yyyy_MM_dd_HH_mm_cn = "yyyy年MM月dd日 HH时mm分";
public static final String yyyy_MM_dd = "yyyy-MM-dd";
public static final String yyyy_MM_dd_cn = "yyyy年MM月dd日";
public static final String HH_mm_ss = "HH:mm:ss";
public static final String HH_mm = "HH:mm";
public static final String HH_mm_ss_cn = "HH时mm分ss秒";
/**
* parse datetime
*
* @param datetime
* @param formatter
* @return
*/
public static LocalDateTime parseLocalDateTime(String datetime, String formatter) {
return LocalDateTime.parse(datetime, DateTimeFormatter.ofPattern(formatter));
}
/**
* parse date
*
* @param date
* @param formatter
* @return
*/
public static LocalDate parseLocalDate(String date, String formatter) {
return LocalDate.parse(date, DateTimeFormatter.ofPattern(formatter));
}
/**
* parse time
*
* @param time
* @param formatter
* @return
*/
public static LocalTime parseLocalTime(String time, String formatter) {
return LocalTime.parse(time, DateTimeFormatter.ofPattern(formatter));
}
/**
* format datetime
*
* @param datetime
* @param formatter
* @return
*/
public static String formatLocalDateTime(LocalDateTime datetime, String formatter) {
return datetime.format(DateTimeFormatter.ofPattern(formatter));
}
/**
* format date
*
* @param date
* @param formatter
* @return
*/
public static String formatLocalDate(LocalDate date, String formatter) {
return date.format(DateTimeFormatter.ofPattern(formatter));
}
/**
* format time
*
* @param time
* @param formatter
* @return
*/
public static String formatLocalTime(LocalTime time, String formatter) {
return time.format(DateTimeFormatter.ofPattern(formatter));
}
/**
* 日期相隔天数
*
* @param start
* @param end
* @return
*/
public static long betweenDays(LocalDate start, LocalDate end) {
return ChronoUnit.DAYS.between(start, end);
}
/**
* 日期相隔小时
*
* @param start
* @param end
* @return
*/
public static long betweenHours(LocalDateTime start, LocalDateTime end) {
return Duration.between(start, end).toHours();
}
/**
* 日期相隔分钟
*
* @param start
* @param end
* @return
*/
public static long betweenMinutes(LocalDateTime start, LocalDateTime end) {
return Duration.between(start, end).toMinutes();
}
/**
* 日期相隔毫秒数
*
* @param start
* @param end
* @return
*/
public static long betweenMillis(LocalDateTime start, LocalDateTime end) {
return Duration.between(start, end).toMillis();
}
/**
* LocalDate --> Date
*
* @param localDate
* @return
*/
public static Date localDate2Date(LocalDate localDate) {
return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
}
/**
* LocalDateTime --> Date
*
* @param localDateTime
* @return
*/
public static Date localDateTime2Date(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
}
/**
* Date --> LocalDate
*
* @param date
* @return
*/
public static LocalDate date2LocalDate(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate();
}
/**
* Date --> LocalDateTime
*
* @param date
* @return
*/
public static LocalDateTime date2LocalDateTime(Date date) {
return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
/**
* timeMillis --> LocalDate
*
* @param timeMillis
* @return
*/
public static LocalDate timeMillis2LocalDate(Long timeMillis) {
return Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDate();
}
/**
* timeMillis --> LocalTime
*
* @param timeMillis
* @return
*/
public static LocalTime timeMillis2LocalTime(Long timeMillis) {
return Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalTime();
}
/**
* timeMillis --> LocalDateTime
*
* @param timeMillis
* @return
*/
public static LocalDateTime timeMillis2LocalDateTime(Long timeMillis) {
return Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDateTime();
}
/**
* LocalDate --> timeMillis
*
* @param localDate
* @return
*/
public static Long localDate2timeMillis(LocalDate localDate) {
return localDate2Date(localDate).getTime();
}
/**
* LocalTime --> timeMillis
*
* @param localTime
* @return
*/
public static Long localTime2timeMillis(LocalTime localTime) {
return localDateTime2timeMillis(LocalDateTime.of(LocalDate.of(1970, 1, 1), localTime));
}
/**
* LocalDateTime --> timeMillis
*
* @param localDateTime
* @return
*/
public static Long localDateTime2timeMillis(LocalDateTime localDateTime) {
return localDateTime2Date(localDateTime).getTime();
}
/**
* 获取2个日期之间的所有日期(闭区间(即: 包括首尾))
*
* @param startDate
* @param endDate
* @return
*/
public static List<LocalDate> getDatesBetween2Dates(LocalDate startDate, LocalDate endDate) {
if (startDate.isAfter(endDate)) {
throw new RuntimeException("开始日期不能晚于结束日期");
}
List<LocalDate> localDates = new ArrayList<>();
LocalDate item = startDate;
while (!item.isAfter(endDate)) {
localDates.add(item);
item = item.plusDays(1);
}
return localDates;
}
/**
* 获取2个日期之间的所有日期(闭区间(即: 包括首尾))
*
* @param startDate
* @param endDate
* @return
*/
public static List<LocalDate> getDatesBetween2DatesV2(LocalDate startDate, LocalDate endDate) {
if (startDate.isAfter(endDate)) {
throw new RuntimeException("开始日期不能晚于结束日期");
}
return Stream.iterate(startDate, date -> date.plusDays(1)).limit(ChronoUnit.DAYS.between(startDate, endDate) + 1).collect(Collectors.toList());
}
/**
* 该日期所在月份的第一天
*
* @param date
* @return
*/
public static LocalDate getFirstDateOfMonth(LocalDate date) {
return LocalDate.of(date.getYear(), date.getMonthValue(), 1);
}
/**
* 该日期所在月份的最后一天
*
* @param date
* @return
*/
public static LocalDate getLastDateOfMonth(LocalDate date) {
return LocalDate.of(date.getYear(), date.getMonthValue(), date.lengthOfMonth());
}
/**
* 该日期所在的周在一年当中是第几周(这里的周指 ISO 标准周)
*
* @param date 指定日期
* @return
*/
public static int getWeekOfWeekBasedYear(LocalDate date) {
/** ISO标准周: 周一为每周的第一天 */
// 第一周: 本年度第一个至少有 4 天的周,WeekFields 源码中也是这样定义的: WeekFields ISO = new WeekFields(DayOfWeek.MONDAY, 4));
// 至少有 4 天,换句话说就是本年度就是第一个周四所在的周;
// 第一周和最后一周是有可能跨年的,示例: 2025年的第一周为: 2024-12-30 ~ 2025-01-05;
/** SUNDAY_START: 周日为每周的第一天,适用于北美和部分欧洲国家 */
// 第一周: 第一个至少有 1 天的周
return date.get(WeekFields.ISO.weekOfWeekBasedYear());
}
/**
* 该日期所在的周对应的年份(这里的周指 ISO 标准周)
* 第一周和最后一周是有可能跨年的,示例: 2025年的第一周为: 2024-12-30 ~ 2025-01-05;因此 2024-12-30 和 2024-12-31 所在周对应的年份也是 2025
*
* @param date 指定日期
* @return
*/
public static int getWeekBasedYear(LocalDate date) {
return date.get(WeekFields.ISO.weekBasedYear());
}
/**
* 查看指定年份指定周对应的周一(这里的周指 ISO 标准周)
*
* @param year 示例: 2024
* @param weekOfYear 第几周
* @return
*/
public static LocalDate getMondayByWeekOfYear(int year, int weekOfYear) {
// 获取指定年份的第一天
LocalDate firstDayOfYear = LocalDate.of(year, 1, 1);
// 第一个周四
LocalDate firstThursday = firstDayOfYear.with(TemporalAdjusters.nextOrSame(DayOfWeek.THURSDAY));
// 第一个周一
LocalDate mondayOfFirstWeek = firstThursday.minusDays(3);
return mondayOfFirstWeek.plusWeeks(weekOfYear - 1);
}
/**
* 该日期所在周的周一
*
* @param date
* @return
*/
public static LocalDate getDateOfMonday(LocalDate date) {
return date.minusDays(date.getDayOfWeek().getValue() - 1);
}
/**
* 该日期所在周的周日
*
* @param date
* @return
*/
public static LocalDate getDateOfSunday(LocalDate date) {
return date.plusDays(7 - date.getDayOfWeek().getValue());
}
/**
* 某天的 00:00:00
*
* @param date
* @return
*/
public static LocalDateTime getDayBegin(LocalDate date) {
return LocalDateTime.of(date, LocalTime.of(0, 0, 0));
}
/**
* 某天的 23:59:59
*
* @param date
* @return
*/
public static LocalDateTime getDayEnd(LocalDate date) {
return LocalDateTime.of(date, LocalTime.of(23, 59, 59));
}
/**
* 该日期所在的季度
*
* @param date 指定日期
* @return 1, 2, 3, 4
*/
public static Integer getQuarter(LocalDate date) {
return (int) Math.ceil(LocalDate.now().getMonthValue() / 3.0);
}
/**
* 格式化时间段
*
* @param millis 毫秒
* @return
*/
public static String formatDuring(long millis) {
if (Long.valueOf(0L).equals(millis)) {
return "0毫秒";
}
long days = millis / (1000 * 60 * 60 * 24);
long left = millis % (1000 * 60 * 60 * 24);
long hours = left / (1000 * 60 * 60);
left = left % (1000 * 60 * 60);
long minutes = left / (1000 * 60);
left = left % (1000 * 60);
long seconds = left / 1000;
left = left % 1000;
String s = days > 0 ? (days + "天") : ("");
s += hours > 0 ? (hours + "小时") : ("");
s += minutes > 0 ? (minutes + "分钟") : ("");
s += seconds > 0 ? (seconds + "秒") : ("");
s += left > 0 ? (left + "毫秒") : ("");
return s;
}
// 节假日
// https://timor.tech/api/holiday/
@Test
public void parseTest() {
System.err.println(parseLocalDateTime("2020-01-01 10:10:10.100", yyyy_MM_dd_HH_mm_ss_SSS));
System.err.println(parseLocalDateTime("2020-01-01 10:10:10", yyyy_MM_dd_HH_mm_ss));
System.err.println(parseLocalDate("2020-01-01", yyyy_MM_dd));
System.err.println(parseLocalTime("10:10:10", HH_mm_ss));
}
@Test
public void formatTest() {
System.err.println(formatLocalDateTime(LocalDateTime.now(), yyyy_MM_dd_HH_mm_ss_SSS));
System.err.println(formatLocalDateTime(LocalDateTime.now(), yyyy_MM_dd_HH_mm_ss));
System.err.println(formatLocalDate(LocalDate.now(), yyyy_MM_dd));
System.err.println(formatLocalTime(LocalTime.now(), HH_mm_ss));
}
@Test
public void betweenTest() {
System.out.println(betweenDays(LocalDate.of(2020, 6, 1), LocalDate.of(2020, 7, 1)));
System.out.println(betweenHours(LocalDateTime.now(), LocalDateTime.now().plusHours(100)));
System.out.println(betweenMinutes(LocalDateTime.now(), LocalDateTime.now().plusMinutes(100)));
System.out.println(betweenMillis(LocalDateTime.now(), LocalDateTime.now().plusHours(100)));
}
@Test
public void convertTest() {
System.err.println(localDate2Date(LocalDate.now()));
System.err.println(localDateTime2Date(LocalDateTime.now()));
System.err.println(date2LocalDate(new Date()));
System.err.println(date2LocalDateTime(new Date()));
}
@Test
public void millisTest() {
System.out.println(timeMillis2LocalDate(System.currentTimeMillis()));
System.out.println(timeMillis2LocalTime(System.currentTimeMillis()));
System.out.println(timeMillis2LocalDateTime(System.currentTimeMillis()));
System.err.println(localDate2timeMillis(LocalDate.now()));
System.err.println(localTime2timeMillis(LocalTime.now()));
System.err.println(localDateTime2timeMillis(LocalDateTime.now()));
}
@Test
public void getMondayByWeekOfYearTest() {
LocalDate secondWeekOf2024 = getMondayByWeekOfYear(2024, 2);
LocalDate firstWeekOf2025 = getMondayByWeekOfYear(2025, 1);
LocalDate firstWeekOf2027 = getMondayByWeekOfYear(2027, 1);
System.err.println(secondWeekOf2024);
System.err.println(firstWeekOf2025);
System.err.println(firstWeekOf2027);
}
@Test
public void getWeekBasedYearTest() {
int year = getWeekBasedYear(LocalDate.of(2024, 12, 30));
System.err.println(year);
}
@Test
public void getDatesBetween2DatesTest() {
List<LocalDate> dates = getDatesBetween2Dates(LocalDate.of(2025, 1, 1), LocalDate.of(2025, 2, 15));
System.err.println(dates);
}
@Test
public void getDatesBetween2DatesV2Test() {
List<LocalDate> dates = getDatesBetween2DatesV2(LocalDate.of(2025, 1, 1), LocalDate.of(2025, 2, 15));
System.err.println(dates);
}
/**
* 补充:
*
* mysql数据类型 - java数据类型
* time - LocalTime/java.sql.Time
* date - LocalDate/java.sql.Date
* datetime - LocalDateTime/java.util.Date
*
* java8 日期类 和 mysql 的字段类型映射,需满足: mysql 驱动包版本不低于 4.2
* <dependency>
* <groupId>mysql</groupId>
* <artifactId>mysql-connector-java</artifactId>
* <version>5.1.37</version>
* </dependency>
*
* 如果使用 mybatis,则还需添加依赖(mybatis-plus 较新版本已经做了支持,不需要该依赖)
* <dependency>
* <groupId>org.mybatis</groupId>
* <artifactId>mybatis-typehandlers-jsr310</artifactId>
* <version>1.0.1</version>
* </dependency>
*
*/
}