在 Java 8 之前,我们处理日期时间需求时,使用 Date、Calender 和 SimpleDateFormat,来声明时间戳、使用日历处理日期和格式化解析日期时间。但是,这些类的 API 的缺点比较明显,比如可读性差、易用性差、使用起来冗余繁琐,还有线程安全问题。因此,Java 8 推出了新的日期时间类。每一个类功能明确清晰、类之间协作简单、API 定义清晰不踩坑,API 功能强大无需借助外部工具类即可完成操作,并且线程安全。
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.Date;
public class LocalDateTimeUtils {
private static DateTimeFormatter formatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");//线程安全的
//ZoneId zoneSH = ZoneId.of("Asia/Shanghai");//上海-北京
//ZoneId zoneNY = ZoneId.of("America/New_York");//纽约
//ZoneId zoneJST = ZoneOffset.ofHours(9);//东京
//Date转换为LocalDateTime
public static LocalDateTime convertDateToLDT(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
//LocalDateTime转换为Date
public static Date convertLDTToDate(LocalDateTime time) {
return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
}
//获取指定日期的毫秒
public static Long getMilliByTime(LocalDateTime time) {
return time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
}
//获取指定日期的秒
public static Long getSecondsByTime(LocalDateTime time) {
return time.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond();
}
//获取指定时间的指定格式
public static String formatTime(LocalDateTime time,String pattern) {
return time.format(DateTimeFormatter.ofPattern(pattern));
}
//获取当前时间的指定格式
public static String formatNow(String pattern) {
return formatTime(LocalDateTime.now(), pattern);
}
//字符串转LocalDateTime
public static LocalDateTime strToLDT(String dateStr) {
return LocalDateTime.parse(dateStr, formatter);
}
}
//Java 8 中有一个专门的类 Period 定义了日期间隔,通过 Period.between 得到了两个 LocalDate 的差,返回的是两个日期差几年零几月零几天。
// 如果希望得知两个日期之间差几天,直接调用 Period 的 getDays() 方法得到的只是最后的“零几天”,而不是算总的间隔天数
//可以使用 ChronoUnit.DAYS.between 解决这个问题:
LocalDate localDate1 = LocalDate.of(2022, 4, 1);
LocalDate localDate2 = LocalDate.of(2023, 5, 10);
System.out.println(Period.between(localDate1,localDate2).getDays());//9
System.out.println(Period.between(localDate1,localDate2));//P1Y1M9D
System.out.println(ChronoUnit.DAYS.between(localDate1,localDate2));//404