java8中的时间类LocalDate、LocalTime、LocalDateTime使用总结

本文详细介绍了在使用Java8中的LocalDate、LocalTime、LocalDateTime类进行前后端数据交互时,如何解决时间格式问题,包括引入必要库、使用注解调整格式及24小时制显示,并提供了前端传参的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java8中新的时间类LocalDate、LocalTime、LocalDateTime在进行前后端交互和数据持久化时会遇到格式问题和映射问题,总结如下:
1、使用springboot jpa时报错:数据库操作失败,提示【could not deserialize】(无法反序列化)
解决方法:pom文件引入下面的jar包

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-java8</artifactId>
    <version>5.1.2.Final</version>
 </dependency>

2、上面jar包引入后就没再报错,但前端时间字段显示格式不是我们常见的“yyyy-MM-dd hh:mm:ss”,而是下面的样子:

"createTime": {
    "month": "DECEMBER",
    "year": 2018,
    "dayOfMonth": 12,
    "dayOfWeek": "WEDNESDAY",
    "dayOfYear": 346,
    "monthValue": 12,
    "hour": 10,
    "minute": 22,
    "nano": 0,
    "second": 25,
    "chronology": {
        "id": "ISO",
        "calendarType": "iso8601"
}

解决方法:
引入下面的jar包

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>2.8.5</version>
</dependency>

同时在类的时间字段上加上注解:@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss")

@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss")
 private LocalDateTime createTime;
@JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss")
private LocalDateTime updateTime;

现在再看一下返回结果

"createTime": "2018-12-11 06:41:33",
"updateTime": "2018-12-11 06:41:33",

格式完全正确了
3、虽然格式现在已经正确了,但是还有一个小问题:返回结果是12小时制,数据库中是24小时制,一般我们也是用24小时制
screenshot
解决方法:
在@JsonFormat注解中pattern = "yyyy-MM-dd HH:mm:ss",就是把小写的hh换成HH就可以了

   @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private LocalDateTime createTime;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private LocalDateTime updateTime;

返回结果如下:

"createTime": "2018-12-11 18:41:33",
"updateTime": "2018-12-11 18:41:33",

完美解决。
4、我是用的持久化框架是JPA JPA包装的是hibernate,所以第一步用的是hibernate-java8,如果是mybatis的话,请引入下面的jar包

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-typehandlers-jsr310</artifactId>
    <version>1.0.2</version>
</dependency>

5、实际设计中,create_time和update_time这俩字段一般是数据库自动生成,这个时候如果使用JPA的话,需要在相应属性加上注解:@Column(insertable = false, updatable = false)。如下所示:

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @Column(insertable = false, updatable = false)
    private LocalDateTime createTime;
    /**更新时间*/
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @Column(insertable = false, updatable = false)
    private LocalDateTime updateTime;

这样的话我们子新增和更新表数据的时候,这两个字段会使用数据库自动生成和更新。

6、前端在RequestBody中传时间参数,后端用LocalDate、LocalTime、LocalDateTime来接收的话,直接在字段上使用@JsonFormat注解,如下面的operateTime字段。

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    private    LocalDateTime operateTime;

注意前端传的数据一定要严格符合pattern中指定的格式,如果前端传"2019-02-13",而pattern中的格式为"yyyy-MM-dd HH:mm:ss"的话,也会报错,不能自动转成"2019-02-13 00:00:00"。
7、前端在RequestParam和PathVariable中传时间参数的话,上面的方法就不好使了,这时候需要加一个日期转换器,使用Spring中的Converter来实现

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Configuration
public class DateConfig {

    @Bean
    public Converter<String, LocalDate> localDateConverter() {
        return new Converter<String, LocalDate>() {
            @Override
            public LocalDate convert(String source) {
                return LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            }
        };
    }

    @Bean
    public Converter<String, LocalDateTime> localDateTimeConverter() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(String source) {
                return LocalDateTime.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            }
        };
    }
}

把上面代码加入到项目中就可以。

package com.aapoint.util; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAdjusters; public class LocalDateTimeUtil { /** * 比较 localDateTime2 是否在localDateTime1之前(比较大小) * @param localDateTime1 * @param localDateTime2 * @return */ public static Boolean compare(LocalDateTime localDateTime1,LocalDateTime localDateTime2){ return localDateTime1.isBefore(localDateTime2); } /** * 获取当前月份前/后的月份的第一天 * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String firstDay(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,0,i); //获取该月份的第一天 String firstDay = date.with(TemporalAdjusters.firstDayOfMonth()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // System.out.println("第一天为:"+firstDay); return firstDay; } /** * 获取当前月份前/后的月份的最后一天 * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String lastDay(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,0,i); //获取该月份的最后一天 String lastDay = date.with(TemporalAdjusters.lastDayOfMonth()).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // System.out.println("最后一天为:"+lastDay); return lastDay; } /** * 获取当时间前/后的时间(天) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainDay(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,1,i); //获取天 String day = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); // System.out.println("获取的时间为(天):"+day); return day; } /** * 获取当时间前/后的时间(小时) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainHours(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,2,i); //获取该月份的最后一天 String hours = date.format(DateTimeFormatter.ofPattern("HH:mm:ss")); // System.out.println("获取的时间为(小时):"+hours); return hours; } /** * 获取当时间前/后的时间(小时) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainMinutes(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,3,i); //获取该月份的最后一天 String minutes = date.format(DateTimeFormatter.ofPattern("HH:mm:ss")); // System.out.println("获取的时间为(分钟):"+minutes); return minutes; } /** * 获取当时间前/后的时间(小时) * @param i 指定距离当前月份的时间 * @param state 状态 0.当月 1.前 2.后 * @return */ public static String obtainSeconds(Integer state,Integer i){ LocalDateTime date = null; //type 类型 0.月 1.天 2.小时 3.分钟 4.秒 date = getLocalDateTime(state,4,i); //获取该月份的最后一天 String seconds = date.format(DateTimeFormatter.ofPattern("HH:mm:ss")); // System.out.println("获取的时间为(秒):"+seconds); return seconds; } public static void main(String[] args) { System.out.println("当前时间为:"+LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); System.out.println("前一个月份的第一天为:"+LocalDateTimeUtil.firstDay(1,1)); System.out.println("前一个月份的最后一天为:"+LocalDateTimeUtil.lastDay(1,1)); System.out.println("当前时间的前一天为:"+LocalDateTimeUtil.obtainDay(1,1)); System.out.println("当前时间的后一天为:"+LocalDateTimeUtil.obtainDay(2,1)); System.out.println("当前时间的前一小时为:"+LocalDateTimeUtil.obtainHours(1,1)); System.out.println("当前时间的后一小时为:"+LocalDateTimeUtil.obtainHours(2,1)); System.out.println("当前时间的前一分钟为:"+LocalDateTimeUtil.obtainMinutes(1,1)); System.out.println("当前时间的后一分钟为:"+LocalDateTimeUtil.obtainMinutes(2,1)); System.out.println("当前时间的前一秒为:"+LocalDateTimeUtil.obtainSeconds(1,1)); System.out.println("当前时间的后一秒为:"+LocalDateTimeUtil.obtainSeconds(2,1)); } private static LocalDateTime getLocalDateTime(Integer state,Integer type,Integer i) { LocalDateTime date; if(state == 0){ date = LocalDateTime.now(); }else if(state == 1){ if(type == 0) { //获取月 date = LocalDateTime.now().minusMonths(i); }else if(type == 1){ //获取天 date = LocalDateTime.now().minusDays(i); }else if(type == 2){ //获取小时 date = LocalDateTime.now().minusHours(i); }else if(type == 3){ //获取分钟 date = LocalDateTime.now().minusMinutes(i);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值