前言
java1.8之前使用的日期java.util.Date和java.util.Calendar类都是可变的,DateFormat方法也是线程不安全(不能以单例模式创建格式器实例),导致很多开发人员使用第三方的日期库,如Joda-Time。因此,Oracle决定在原生API上提供更好的日期时间支持,在java1.8的java.time包中整合了很多Joda-Time的特性,并且这些类都是不可变和线程安全的。
日期使用
LocalDate
LocalDate localDate = LocalDate.now();
System.out.println("获取当前日期:" + localDate);
int year = localDate.getYear();
int month = localDate.getMonthValue();
int day = localDate.getDayOfMonth();
System.out.printf("当前日期分别获取的年月日,年:%d, 月份:%d, 日:%d %n", year, month, day);
System.out.println("获取当月天数:" + localDate.lengthOfMonth());
System.out.println("获取当天星期几:" + localDate.getDayOfWeek());
System.out.println("获取当月的第几天:" + localDate.getDayOfMonth());
System.out.println("获取明天的日期:" + localDate.plusDays(1));
System.out.println("获取昨天的日期:" + localDate.minusDays(1));
System.out.println("获取上月当天日期:" + localDate.minusMonths(1));
System.out.println("获取当月第一天:" + localDate.with(firstDayOfMonth()));
System.out.println("获取当月最后一天:" + localDate.with(lastDayOfMonth()));
System.out.println("是否闰年:" + localDate.isLeapYear());
LocalDate localDate1 = LocalDate.of(2019, 12, 31);
System.out.println("获取指定日期:" + localDate1);
System.out.println("获取上月的指定日期:" + localDate1.minusMonths(1));
System.out.println("获取日期相差天数:" + localDate.until(localDate1, ChronoUnit.DAYS));
System.out.println("当前日期是否在指定日期后:" + localDate.isAfter(localDate1));
System.out.println("当前日期是否等于指定日期:" + localDate.isEqual(localDate1));
System.out.println("当前日期是否在指定日期前:" + localDate.isBefore(localDate1));
LocalDate localDate2 = LocalDate.parse("2019-12-17");
System.out.println("解析字符串日期:" + localDate2);
输出为:
获取当前日期:2019-12-04
当前日期分别获取的年月日,年:2019, 月份:12, 日:4
获取当月天数:31
获取当天星期几:WEDNESDAY
获取当月的第几天:4
获取明天的日期:2019-12-05
获取昨天的日期:2019-12-03
获取上月当天日期:2019-11-04
获取当月第一天:2019-12-01
获取当月最后一天:2019-12-31
是否闰年:false
获取指定日期:2019-12-31
获取上月的指定日期:2019-11-30
获取日期相差天数:27
当前日期是否在指定日期后:false
当前日期是否等于指定日期:false
当前日期是否在指定日期前:true
解析字符串日期:2019-12-17
LocalTime
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("获取当前日期时间:" + localDateTime);
System.out.println("获取不带毫秒的当前日期时间:" + localDateTime.withNano(0));
System.out.println("当前日期时间提取日期:" + localDateTime.toLocalDate());
System.out.println("当前日期时间提取时间:" + localDateTime.toLocalTime());
LocalDateTime localDateTime1 = LocalDateTime.of(localDate, localTime);
System.out.println("日期和时间的合并:" + localDateTime1);
LocalDateTime localDateTime2 = LocalDateTime.of(2019, 11, 12, 13,14,15);
System.out.println("获取指定的日期时间:" + localDateTime2);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
System.out.println("格式化为yyyyMMdd的日期时间:" + localDateTime2.format(dateTimeFormatter));
//2019-11-13T13:14:15
System.out.println("明天的当前日期时间:" + localDateTime2.plusDays(1));
输出为:
获取当前日期时间:2019-12-04T01:07:21.244
获取不带毫秒的当前日期时间:2019-12-04T01:07:21
当前日期时间提取日期:2019-12-04
当前日期时间提取时间:01:07:21.244
日期和时间的合并:2019-12-04T01:07:21.243
获取指定的日期时间:2019-11-12T13:14:15
格式化为yyyyMMdd的日期时间:20191112131415
明天的当前日期时间:2019-11-13T13:14:15
Instant的使用
System.out.println("获取当前时间戳:" + Instant.now());
输出为:
获取当前时间戳:2019-12-03T17:07:21.246Z
Duration
Duration类主要用于以秒和纳秒衡量时间的长短, 不能LocalDate作为参数,否则会报错.
Duration duration = Duration.between(localDateTime1, localDateTime1.plusSeconds(1));
Duration duration1 = Duration.between(localTime1, localTime1.plusSeconds(1));
System.out.println("两个localDateTime相差的秒数:" + duration.getSeconds());
System.out.println("两个localTime相差的秒数:" + duration1.getSeconds());
输出为:
两个localDateTime相差的秒数:1
两个localTime相差的秒数:1
Period
Period period = Period.between(LocalDate.of(2019, 3, 8),
LocalDate.of(2019, 3, 18));
System.out.println("两个LocalDate相差的天数:" + period.getDays());
输出为:
两个LocalDate相差的天数:10
TemporalAdjuster
对日期时间更复杂的操作,静态工厂类方法TemporalAdjusters提供了很多对日期的操作. TemporalAdjuster接口(函数式接口):
@FunctionalInterface
public interface TemporalAdjuster {
Temporal adjustInto(Temporal var1);
}
使用:
//使用重载的with方法
LocalDate localDate3 = localDate.with(nextOrSame(DayOfWeek.SUNDAY));
System.out.println("第一个符合指定星期几的日期:" + localDate3);
//自定义TemporalAdjuster,简单的例子:下一年的第一天,以下使用了三种方式
//1.使用Lambda表达式定义TemporalAdjuster对象,使用TemporalAdjusters类的静态工厂方法ofDateAdjuster
TemporalAdjuster nextDate = TemporalAdjusters.ofDateAdjuster(temporal -> temporal.plusDays(1));
LocalDate adjustDate = localDate.with(nextDate);
System.out.println("Lambda表达式定义TemporalAdjuster对象方式:下一年的第一天:" + adjustDate);
//2.Lambda表达式的方式
adjustDate = localDate.with(temporal -> temporal.plus(1, ChronoUnit.DAYS));
System.out.println("Lambda表达式方式:下一年的第一天:" + adjustDate);
//3.实现TemporalAdjuster接口
adjustDate =localDate.with(new NextDay());
System.out.println("实现TemporalAdjuster接口方式:" + adjustDate);
输出:
第一个符合指定星期几的日期:2019-12-08
Lambda表达式定义TemporalAdjuster对象方式:下一年的第一天:2019-12-05
Lambda表达式方式:下一年的第一天:2019-12-05
实现TemporalAdjuster接口方式:2019-12-05
Date和LocalDate,LocalDateTime,的相互转换
//Date和LocalDate,LocalDateTime,的相互转换
Date date = new Date();
ZoneId defaultZoneId = ZoneId.systemDefault();
Instant instant = date.toInstant();
LocalDate localDate4 = instant.atZone(defaultZoneId).toLocalDate();
System.out.println("Date->LocalDate:" + localDate4);
LocalDateTime localDateTime3 = instant.atZone(defaultZoneId).toLocalDateTime();
System.out.println("Date->localDateTime:" + localDateTime3);
LocalDate localDate5 = LocalDate.of(2019, 12, 2);
instant = localDate5.atStartOfDay(defaultZoneId).toInstant();
System.out.println("LocalDate->Date:" + Date.from(instant));
LocalDateTime localDateTime4 = LocalDateTime.of(2019,12,03,11,24,23);
instant = localDateTime4.atZone(defaultZoneId).toInstant();
System.out.println("LocalDateTime->Date:" + Date.from(instant));
输出:
Date->LocalDate:2019-12-04
Date->localDateTime:2019-12-04T01:07:21.252
LocalDate->Date:Mon Dec 02 00:00:00 CST 2019
LocalDateTime->Date:Tue Dec 03 11:24:23 CST 2019
计算时间差
Instant startInstant = Instant.now();
Thread.sleep(10L);
Instant endInstant = Instant.now();
System.out.println("计算时间差:" + startInstant.until(endInstant, ChronoUnit.MILLIS) + "ms");
输出:
计算时间差:11ms
时间戳和LocalDateTime的相互转换
LocalDateTime localDateTime5 = LocalDateTime.now();
long timestamp = localDateTime5.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
System.out.println("localDateTime->timestamp:" + timestamp);
Instant instant1 = Instant.ofEpochMilli(timestamp);
LocalDateTime localDateTime6 = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault());
System.out.println("timestamp->localDateTime:" + localDateTime6);
输出:
localDateTime->timestamp:1575392841270
timestamp->localDateTime:2019-12-04T01:07:21.270
Monthday 和 YearMonth
MonthDay monthDay = MonthDay.now();
YearMonth yearMonth = YearMonth.now();
System.out.println("MonthDay:" + monthDay);
System.out.println("YearMonth:" + yearMonth);
LocalDateTime localDateTime7 = LocalDateTime.now();
YearMonth yearMonth1 = YearMonth.from(localDateTime7);
System.out.println("LocalDateTime->YearMonth:" + yearMonth1);
输出:
MonthDay:--12-04
YearMonth:2019-12
LocalDateTime->YearMonth:2019-12