分析java8的LocalDateTime类及使用的注意事项

jdk8中新增的java.time包真的是不要太棒,jdk8以前的date存在着线程不安全、api难用等问题。来看看新的date有些什么特点:

1、使用不可变对象保证线程安全

LocalDateTime中有两个final修饰的成员,date表示日期(年月日部分),time表示时间(时分秒部分)。

	/**
     * The date part.
     */
    private final LocalDate date;
    /**
     * The time part.
     */
    private final LocalTime time;

LocalDate中直接使用year、month、day三个成员变量表示年月日,LocalTime中使用hour、minute、second、nano表示时分秒和纳秒。底层源码看起来很清晰易懂。
对LocalDateTime对象的任何修改操作都会生成一个新的实例返回,也就是说LocalDateTime对象本身一旦生成是不可变的。多线程操作中也无需考虑线程安全问题,因为本身API层面就不支持修改。

2、新老API实现时间的加减运算

使用旧的API实现在当前时间上加一个小时的操作:

	@Test
    public void testDate(){
        Date date = new Date();
        System.out.println(date);
        date.setHours(date.getHours()+1);
        System.out.println(date);
    }

java.util.Date的setHours和getHours方法已经过去,推荐使用Calendar

    @Test
    public void testDate2(){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.HOUR_OF_DAY, 1);
        System.out.println(calendar.getTime());
    }

使用LocalDateTime

    @Test
    public void test1(){
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime.toString());
        LocalDateTime localDateTime2= localDateTime.plusHours(1L);
        System.out.println(localDateTime2.toString());
    }

个人觉得使用Calendar需要了解Calendar和Date的关系,了解其add方法的用法,使用LocalDateTime直接根据方法名就知道是干嘛的,更不用说字符串和Date互转有多麻烦了。以前一直不懂为啥对Date的操作还要通过Calendar去完成,LocalDateTime的设计更加符合单一职责的原则,更加符合使用习惯。

3、需要注意的地方

3.1、LocalDateTime的toString方法并不是标准的时间格式的输出

在这里插入图片描述
貌似很正常,再看一个正好秒为0的
在这里插入图片描述
秒不见了,不是标准的格式哟。
同样有个格式化的工具DateTimeFormatter
在这里插入图片描述

3.2、转json字符串时需要配置序列化工具

测试jackson和fastjson两种方式:

    @Test
    public void testParseJson() throws JsonProcessingException {
        LocalTimeDateTestDto localTimeDateTestDto = new LocalTimeDateTestDto(LocalDateTime.now());
        //jackson方式转换
        ObjectMapper objectMapper = new ObjectMapper();
        System.out.println("jackson方式转换: "+objectMapper.writeValueAsString(localTimeDateTestDto));
        //fastjson方式转换
        System.out.println("fastjson方式转换: " + JSON.toJSONString(localTimeDateTestDto));
    }

@Data
@AllArgsConstructor
class LocalTimeDateTestDto{
    private LocalDateTime time;
}

结果

jackson方式转换: {"time":{"year":2020,"month":"MARCH","nano":537000000,"monthValue":3,"dayOfMonth":30,"hour":20,"minute":49,"second":3,"dayOfYear":90,"dayOfWeek":"MONDAY","chronology":{"id":"ISO","calendarType":"iso8601"}}}
fastjson方式转换: {"time":"2020-03-30T20:49:03.537"}

fastjson还是能正常转换的,jackson就离我们的预想差得有点儿远了。
再看字符串转Object,fastjson使用字符串{“time”:“2020-03-30T20:49:03.537”}还是可以成功转为LocalTimeDateTestDto的。
在这里插入图片描述
最后,修复jackson方式还是有办法的:
改造LocalTimeDateTestDto,配置jackson的序列化工具和反序列化工具,还可使用@JsonFormat指定特定的格式

@Data
@NoArgsConstructor
@AllArgsConstructor
public class LocalTimeDateTestDto{

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS")
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    private LocalDateTime time;
}

再测试对象转字符串
在这里插入图片描述
字符串转Object
在这里插入图片描述

发布了34 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_36142042/article/details/105206553
今日推荐