Java8不可或缺小帮手之日期应用

2023-05-20 05:05:15 日期 不可或缺 小帮手

jdk1.8后引入了新的日期时间处理api,相比传统的date操作更加简便,date中的SimpleDateFORMat也是非线程安全的。

新的API是标准的ISO-8601日历系统,位于java.time包下,且所有类都是不可变类型、线程安全。

废话不多说,开干。

1、获取当前日期时间

now() :静态方法,根据当前时间创建对象。例如:获取当前日期,当前时间,当前日期时间

//获取当前日期
LocalDate nowDate = LocalDate.now();
System.out.println("获取当前日期:"+nowDate);
//获取当前时间
LocalTime nowTime = LocalTime.now();
System.out.println("获取当前时间:"+nowTime);
//获取当前日期时间
LocalDateTime nowDateTime = LocalDateTime.now();
System.out.println("获取当前日期时间:"+nowDateTime);

输出:

获取当前日期:2023-05-11
获取当前时间:11:10:10.453
获取当前日期时间:2023-05-11T11:10:10.454

2、日期时间格式化

DateTimeFormatter:静态格式化类,提供了ofPattern,ofLocalizedDate,format等格式化方法。

方法描述
ofPattern(String pattern)格式化样式定义,例如:yyyy-MM-dd等
format(TemporalAccessor temporal)执行格式化,返回字符串类型的时间样式,如:2023-05-11
ofLocalizedDate(FormatStyle dateStyle)返回特定区域的日期格式。FormatStyle提供了四种类型,分别是:FULL、LONG,SHORT、MEDIUM
ofLocalizedTime(FormatStyle dateStyle)返回特定区域的时间格式。
ofLocalizedDateTime(FormatStyle dateStyle)返回特定区域的日期时间格式

注:在使用ofLocalizedTime,ofLocalizedDateTime中的FormatStyle.FULL,FormatStyle.LONG时由于时区信息问题,通常不存储在LocalTime,LocalDateTime对象中,因此会报取不到值的错误。如:

private static final DateTimeFormatter TIME_DTF = DateTimeFormatter.ofPattern("hh:mm:ss");
private static final DateTimeFormatter DATE_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter DATE_TIME_DTF = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");

//格式化
System.out.println("日期格式化:" + DATE_DTF.format(nowDate));
System.out.println("时间格式化:" + TIME_DTF.format(nowTime));
System.out.println("日期时间格式化:" + DATE_TIME_DTF.format(nowDateTime));

System.out.println("日期样式:" + DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(nowDate));
System.out.println("日期样式:" + DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(nowDate));
System.out.println("日期样式:" + DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(nowDate));
System.out.println("日期样式:" + DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(nowDate));

//System.out.println("时间样式:" + DateTimeFormatter.ofLocalizedTime(FormatStyle.FULL).format(LocalTime.now()));
System.out.println("时间样式:" + nowTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM)));
// System.out.println("时间样式:" + nowTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.LONG)));
System.out.println("时间样式:" + nowTime.format(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)));

System.out.println("日期时间样式:" + DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).format(nowDateTime));

输出:

日期格式化:2023-05-11
时间格式化:11:43:48
日期时间格式化:2023-05-11 11:43:48
日期样式:2023年5月11日 星期四
日期样式:2023-5-11
日期样式:23-5-11
日期样式:2023年5月11日
时间样式:11:43:48
时间样式:上午11:43
日期时间样式:2023-5-11 11:43:48

3、获取日期的年月日

在Date中获取月份是从0开始的,因此真正的月份是需要加1的。而LocalDate提供的方法则不需要。

  • getYear() :获取年份,返回int,
  • getMonthValue() :获取月份值,相当于是getMonth().getValue()。
  • getMonth() :获取的是月份枚举类型,存储的是英文的月份,可以通过getValue()获取int的月份
  • getDayOfMonth() :获取月份中第几天,
  • getDayOfYear() :获取当前日期在一年中的第几天。
  • getDayOfWeek() :获取星期,返回DayOfWeek枚举,保存英文星期,通过getValue()获取数字星期几。
//获取年月日
int year = nowDate.getYear();
int monthValue = nowDate.getMonthValue();
int month = nowDate.getMonth().getValue();
int day = nowDate.getDayOfMonth();
int dayOfYear = nowDate.getDayOfYear();
int dayOfWeek = nowDate.getDayOfWeek().getValue();
System.out.println("year:" + year + ",monthValue:" + monthValue +
        ",month:" + month + ",day:" + day +
        ",dayOfYear:" + dayOfYear + ",dayOfWeek:" + dayOfWeek );

输出:

year:2023,monthValue:5,month:5,day:11,dayOfYear:131,dayOfWeek:4

4、时间转换

时间转换,包括Date转LocalDate、LocalTime、LocalDateTime;LocalDateTime转Date,String转LocalDate、LocalTime、LocalDateTime等。

parse(CharSequence text) :将字符串转成对应的LocalDate,LocalTime,LocalDateTime。

LocalDate of(int year, int month, int dayOfMonth) /LocalDate of(int year, Month month, int dayOfMonth) :设置年月日,转成LocalDate。

如下面代码:

//of()
LocalDate ofDate = LocalDate.of(2022, Month.JANUARY, 31);
        System.out.println("of方法转LocalDate;" + ofDate);
//String转LocalDate,LocalTime,LocalDateTime
String date = "2020-01-01";
String time = "11:22:33";
String dateTime = "2021-09-06T09:51:51";
LocalDate localDate = LocalDate.parse(date);
LocalTime localTime= LocalTime.parse(time);
LocalDateTime localDateTime = LocalDateTime.parse(dateTime);
System.out.println("String转LocalDate,LocalTime,LocalDateTime,LocalDate;" +
        localDate + ",LocalTime:" + localTime + ",LocalDateTime:"+localDateTime);
 //date转LocalDate,LocalTime,LocalDateTime
Date date1 = new Date();
LocalDate localDate1 = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault()).toLocalDate();
LocalDateTime localDateTime1 = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault());
LocalTime localTime1 = LocalDateTime.ofInstant(date1.toInstant(), ZoneId.systemDefault()).toLocalTime();
System.out.println("date转LocalDate,LocalTime,LocalDateTime,LocalDate;" +
    localDate1 + ",LocalTime:" + localTime1 + ",LocalDateTime:"+localDateTime1);
//LocalDateTime转Date
Date from = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
System.out.println("LocalDateTime转Date;" + from );

输出:

of方法转LocalDate;2022-01-31
String转LocalDate,LocalTime,LocalDateTime,LocalDate;2020-01-01,LocalTime:11:22:33,LocalDateTime:2021-09-06T09:51:51
date转LocalDate,LocalTime,LocalDateTime,LocalDate;2023-05-11,LocalTime:14:30:02.562,LocalDateTime:2023-05-11T14:30:02.562
LocalDateTime转Date;Thu May 11 14:30:02 CST 2023

5、日期比较

LocalDate中提供了equals,isAfter,isBefore等方法来对日期进行比较,这对于我们业务代码中时间判断带来了很大的方法。

equals(Object obj) :对比两个日期是否相等,查看源码会发现,首先比较的是对象是否一样,然后分别做年,月,日的差是否等于0来进行比较。true:表示相等,false:表示不相等

compareTo(ChronoLocalDate other) :比较日期,0:表示相等,正数:表示大于,负数:表示小于。

isAfter(ChronoLocalDate other) :日期是否在other之后,true:表示是,false:表示否。相当于compareTo正负数。

isBefore(ChronoLocalDate other) :日期是否在other之前,true:表示是,false:表示否。相当于compareTo正负数。

//时间比较
LocalDate firDate = LocalDate.of(2022, 11, 23);
LocalDate secDate = LocalDate.of(2023, 11, 23);
LocalDate thrDate = LocalDate.of(2021, 11, 23);
//equals
System.out.println("equals:" + firDate.equals(secDate));
//compareTo
System.out.println("compareTo1:" + secDate.compareTo(thrDate));
System.out.println("compareTo2:" + thrDate.compareTo(firDate));
//isAfter
System.out.println("isAfter:" + firDate.isAfter(secDate));
System.out.println("isAfter:" + secDate.isAfter(thrDate));
//isBefore
System.out.println("isBefore:" + firDate.isBefore(secDate));
System.out.println("isBefore:" + secDate.isBefore(thrDate));

输出:

equals:false
compareTo1:2
compareTo2:-1
isAfter:false
isAfter:true
isBefore:true
isBefore:false

6、检查周期性日期

在日常生活中,有许多纪念意义的日期,比如说生日,国庆等等。这时候需要进行周期性检查来做一些提醒,比如:老婆的生日,这要是忘了估计跪榴莲都是轻的。哈哈哈

MonthDay这个类,就提供了of,from来获取月份与当前月份中第几天,然后使用equals进行比较即可。

//周期性检查
LocalDate birthDay = LocalDate.of(1991, 5, 11);
MonthDay birthMonth = MonthDay.of(birthDay.getMonth(), birthDay.getDayOfMonth());
MonthDay nowMonth = MonthDay.from(nowDate);
if (Objects.equals(birthMonth,nowMonth)){
    System.out.println("生日到了!");
} else {
    System.out.println("万幸,还好生日还没到呢,差点忘了......!");
}

输出:

生日到了!

7、日期计算

前段时间做了一个需求,需要获取前13个月的日期,这是使用LocalDate就比较方便,来看看LocalDate提供的方法。

提前:

minus(long amountToSubtract, TemporalUnit unit) :计算提前的日期,ChronoUnit实现了TemporalUnit接口,提供了各种日期类型,例如:

ChronoUnit.MONTHS,表示日期。

minusMonths(long monthsToSubtract) :计算提前月份的日期。

minusDays(long daysToSubtract) :计算提前天数的日期。

minusWeeks(long weeksToSubtract) :计算提前星期的日期。

minusYears(long yearsToSubtract) :计算提前年份的日期。

推后:

plus(long amountToSubtract, TemporalUnit unit) :计算推后的日期,ChronoUnit实现了TemporalUnit接口,提供了各种日期类型,例如:

ChronoUnit.MONTHS,表示日期。

plusMonths(long monthsToSubtract) :计算推后月份的日期。

plusDays(long daysToSubtract) :计算推后天数的日期。

plusWeeks(long weeksToSubtract) :计算推后星期的日期。

plusYears(long yearsToSubtract) :计算推后年份的日期。

LocalDate nowDate = LocalDate.now();
//日期计算
//提前
System.out.println("两个月前的日期:" +  nowDate.minusMonths(2));
System.out.println("20天前的日期:" + nowDate.minusDays(20));
System.out.println("1星期前的日期:" + nowDate.minusWeeks(1));
System.out.println("1年前的日期:" + nowDate.minusYears(1));
System.out.println("1个月前的日期:" + nowDate.minus(1, ChronoUnit.MONTHS));
//推后
System.out.println("两个月后的日期:" + nowDate.plusMonths(2));
System.out.println("20天后的日期:" + nowDate.plusDays(20));
System.out.println("1星期后的日期:" + nowDate.plusWeeks(1));
System.out.println("1年后的日期:" + nowDate.plusYears(1));
System.out.println("1个月后的日期:" + nowDate.plus(1,ChronoUnit.MONTHS));

输出:

两个月前的日期:2023-03-11
20天前的日期:2023-04-21
1星期前的日期:2023-05-04
1年前的日期:2022-05-11
1个月前的日期:2023-04-11
两个月后的日期:2023-07-11
20天后的日期:2023-05-31
1星期后的日期:2023-05-18
1年后的日期:2024-05-11
1个月后的日期:2023-06-11

8、处理时区

java8将时区也分离了出来,用ZoneId来处理特定时区。

ZoneDateTime:表示某时区下的时间。

//时区
ZonedDateTime of = ZonedDateTime.of(nowDateTime, ZoneId.of("Asia/Shanghai"));
System.out.println("时区:" + of);

输出:

时区:2023-05-11T16:17:11.479+08:00[Asia/Shanghai]

9、获取时间戳

java8提供了Instant类来对时间戳进行操作。

System.out.println("时间戳:" + Instant.now().getEpochSecond());

时间戳返回的是秒级别的数据。

输出:

时间戳:1683794339

10、闰年判断

isLeapYear() :可以直接查询日期是否为闰年。true:表示是,false:表示否。

boolean leapYear = nowDate.isLeapYear();
if (leapYear){
    System.out.println("闰年!");
} else {
    System.out.println("不是闰年!");
}

输出:

不是闰年!

11、获取第一天和最后一天

有时候我们业务需要获取当月或当年的第一天日期或最后一天日期,TemporalAdjusters类提供了一些方法可以直接实现。

  • TemporalAdjusters.lastDayOfMonth() :月份的最后一天日期。
  • TemporalAdjusters.firstDayOfMonth() :月份的第一天日期。
  • TemporalAdjusters.lastDayOfYear() :年份的最后一天日期。
  • TemporalAdjusters.firstDayOfYear() :年份的第一天日期。

例如:获取当月/当年的第一天日期和最后一天日期。

//获取当月第一天和最后一天
LocalDate lastDay = nowDate.with(TemporalAdjusters.lastDayOfMonth());
LocalDate firstDay = nowDate.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("当月第一天:"+firstDay + ";当月最后一天:" + lastDay);
//获取当年第一天和最后一天
LocalDate lastYearDay = nowDate.with(TemporalAdjusters.lastDayOfYear());
LocalDate firstYearDay = nowDate.with(TemporalAdjusters.firstDayOfYear());
System.out.println("当年第一天:"+firstYearDay + ";当月最后一天:" + lastYearDay);

输出:

当月第一天:2023-05-01;当月最后一天:2023-05-31
当年第一天:2023-01-01;当月最后一天:2023-12-31

上述就是我在工作用到的一些java8日期时间的方法,存在完

以上就是Java8不可或缺小帮手之日期应用的详细内容,更多关于Java8日期的资料请关注其它相关文章!

相关文章