【小家java】java8新特性之---全新的日期、时间API(JSR 310规范),附SpringMVC、Mybatis中使用JSR310的正确姿势(中)

简介: 【小家java】java8新特性之---全新的日期、时间API(JSR 310规范),附SpringMVC、Mybatis中使用JSR310的正确姿势(中)

新的API 格式化(字符串 -><- 字符串 互转)


  public static void main(String[] args) {
        //字符串转化为日期对象
        String dateStr= "2016年10月25日";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
        LocalDate date= LocalDate.parse(dateStr, formatter);
        //日期转换为字符串
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy年MM月dd日 hh:mm a");
        String nowStr = now .format(format);
        System.out.println(nowStr); //2018年08月07日 12:15 上午
    }


  • DateTimeFormatter预定义了一些格式,可以直接调用format方法,方便调用者使用


//2017-01-01
DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.of(2017, 1, 1))
//20170101
DateTimeFormatter.BASIC_ISO_DATE.format(LocalDate.of(2017, 1, 1));
//2017-01-01T09:10:00
DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(LocalDateTime.of(2017, 1, 1, 9, 10, 0)); 

根据当前操作系统语言环境,有SHORET MEDIUM LONG FULL 四种不同的风格来格式化。


可以通过DateTimeFormatter的静态方法ofLocalizedDate ofLocalizedTime ofLocalizedDateTime


  • 使用自定义模式格式化


//2017-02-27 22:48:52
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now())

当然也可以这么搞


//使用的ISO_LOCAL_DATE格式解析  2017-01-01
LocalDate.parse("2017-01-01");
//使用自定义格式解析  2017-01-01T08:08:08
LocalDateTime.parse("2017-01-01 08:08:08", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));


在DateTimeFormatter中还有很多定义好的格式,有兴趣的可以自己去看一下

SimpleDateFormat是线程不安全的,所以在高并发环境下,建议这么搞


 private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };
    //和线程绑定 保证安全
    public static String format(Date date) {
        return threadLocal.get().format(date);


    注意:ofPattern(String pattern)和ofPattern(String pattern, Locale locale)还是有区别的。但绝大多数情况下,我们用ofPattern就够了,因为Locale对象根据用户的国家,地区文化差异格式化,不会改变系统时间,只是表达方式变而已,就是数值表示方法不同而已,也是一样的值,这个方法不常用,因为不能覆盖所有语言环境。并且和格式化模版有关,比如我们的最常用yyyy-MM-dd HH:mm:ss会没有效果。但是这种模版“GGGG yyyy/MMMM/dd HH:mm:ss EEE”,Local不同,展示方式是有很大不同的


Date类型和时间戳 转换成新的时间类型


Date在1.8之后提供了几个方法,可以很方便的转换成新的API


     //时间戳转instant就很简单了
        Instant instant = Instant.ofEpochMilli(System.currentTimeMillis());
        System.out.println(instant); //2018-08-06T16:26:08.539Z(其实已经24点了,所以直接输出是有时区问题的 需要注意)
        //Date直接转Instant
        System.out.println(new Date().toInstant()); //2018-08-06T16:26:08.539Z
        //Instant --> Date
        Date.from(Instant.now());
        //Calendar --> Instant(这个用得很少)
        Calendar.getInstance().toInstant();


理论知识就介绍到这了,接下来看一些有意思的案例实现,可以更好的了解应用场景


根据已经了解的策略模式,我们可以很好的猜到,LocalDate、LocalTime、LocalDateTime他们之前的互相转换,也是可以走from方法的,如下:


LocalDateTime localDateTime = LocalDateTime.now();
        LocalDate localDate = LocalDate.from(localDateTime);
        LocalTime localTime = LocalTime.from(localDateTime);
        System.out.println(localDate); //2018-08-13
        System.out.println(localTime); //16:04:48.356
        ///下面的会报错哟///
        //LocalTime localTime = LocalTime.now();
        //LocalDate localDate = LocalDate.from(localTime); //这样转是会报错的  因为LocalTime不含有Date元素 Unable to obtain LocalDate from TemporalAccessor: 16:01:47.541 of type java.time.LocalTime
        //LocalDateTime localDateTime = LocalDateTime.from(localTime); //这样转也是会报错的 因为不含有date元素
        //System.out.println(localTime);
        //System.out.println(localDateTime);


重要:常用:LocalDate和Date类、时间戳之间转换的坑


Date对象表示特定的日期和时间,而LocalDate(Java8)对象只包含没有任何时间信息的日期。 因此,如果我们只关心日期而不是时间信息,则可以在Date和LocalDate之间进行转换


在JDK8以前,我们经常遇到用Date类型来装载时间。有时候只表示日期,有时候是日期+时间,但是我们的选择都只能是Date类型。因此Date类型到LocalDate、LocalTime、Instant等类型的转换 显得尤为重要了。


这里面需要注意一个坑:他们转换的中间桥梁都是时间戳Instant对象,但是转换的时候如果没有考虑时区,就会报错的。


比如下面这个例子,看起来顺滑,其实异常了:


Date date = new Date();
        Instant instant = date.toInstant();
        //看起来非常顺滑 但其实 异常:Unable to obtain LocalDate from TemporalAccessor: 2018-08-31T02:41:28.076Z of type java.time.Instant
        LocalDate from = LocalDate.from(date.toInstant());


其实这个也好理解。人家Date是带有日期和时间的,然后突然来一个只需要日期的,LocalDate不知道咋处理(或者说JDK8没考虑到这一点,其实不是,因为时区没定,LocalDate自己不好自己做定论),所以不允许直接转换也可以理解。所以各位使用起一定要小心使用了


糗事Date和LocalDate、LocalTime等互相转化的的思想也很简单 借助LocalDateTime对象就万无一失了。


    Date date = new Date();
        Instant instant = date.toInstant();
        //以ZoneId.systemDefault转换成LocalDateTime后,就可以随意转换了
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
        //方式一:使用LocalDate、LocalTime的from
        LocalDate fromLocalDate = LocalDate.from(localDateTime);
        LocalTime fromLocalTime = LocalTime.from(localDateTime);
        System.out.println(fromLocalDate); //2018-08-31
        System.out.println(fromLocalTime); //11:03:19.716
        //方式二:直接to的方式
        LocalDate toLocalDate = localDateTime.toLocalDate();
        LocalTime toLocalTime = localDateTime.toLocalTime();
        System.out.println(toLocalDate); //2018-08-31
        System.out.println(toLocalTime); //11:03:19.716


反向转换:借助的中间变量是Instant即可


 public static void main(String[] args) {
        LocalDateTime localDateTime = LocalDateTime.now();
        LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        Instant instant = null;
        ZoneId zone = ZoneId.systemDefault();
        //LocalDateTime转Instant转Date
        instant = localDateTime.atZone(zone).toInstant();
        System.out.println(Date.from(instant));
        //LocalDate转Instant转Date
        instant = localDate.atStartOfDay().atZone(zone).toInstant();
        System.out.println(Date.from(instant));
        //LocalTime转Instant转Date(很麻烦 一般杜绝这样使用吧)
        //必须先借助localDate转换成localDateTime 在转成instant 再转date
        LocalDateTime localDateTimeDate = LocalDateTime.of(localDate, localTime);
        instant = localDateTime.atZone(zone).toInstant();
        System.out.println(Date.from(instant));
    }



时间矫正器(TemporalAdjuster )


Java8推出了时间矫正器的概念。可以辅助我们更精准的定位到一些日期,比如写个周日,下个结婚纪念日等等。


    TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下个周日”等操作。不过它是个接口,并且是函数式接口


    TemporalAdjusters : 该类通过静态方法提供了大量的常用TemporalAdjuster 的实现。

时间矫正,用的都是with语法。可以理解成和set差不多

image.png



public static void main(String[] args) {
        LocalDateTime ldt1 = LocalDateTime.now();
        //本月第一天
        LocalDateTime ldt2 = ldt1.with(TemporalAdjusters.firstDayOfMonth());
        System.out.println(ldt2); //2018-08-01T17:34:42.039
        //本月的第一个周五
        LocalDateTime ldt3 = ldt1.with(TemporalAdjusters.firstInMonth(DayOfWeek.FRIDAY));
        System.out.println(ldt3); //2018-08-03T17:41:07.619
    }


接下来一个场景会比较有意思点:下一个信用卡还款日是什么时候。



时间矫正器,在很多场景下,还是非常有用的。所以希望读者能够大概掌握


Java中处理日期、时间的经典案例场景


检查两个日期是否相等


LocalDate重写了equals方法来进行日期的比较,如下所示:


image.png


在java8中如何检查重复事件,比如生日


这是相对比较常用的一个场景:判断今天是否是某个人的生日。


image.png

通过列子可以看到MonthDay只存储了月日,对比两个日期的月日即可知道是否重复,而且使用了equals方法,非常的方便快捷有木有

相关文章
|
9月前
|
前端开发 Java 开发者
Java新手指南:在Spring MVC中使用查询字符串与参数
通过结合实际的需求和业务逻辑,开发者可以灵活地利用这些机制,为用户提供更丰富而高效的Web应用体验。
239 15
|
10月前
|
JSON 前端开发 Java
Java新手指南:如何在Spring MVC中处理请求参数
处理Spring MVC中的请求参数是通过控制器方法中的注解来完成的。这些注解包括 `@RequestParam`, `@PathVariable`, `@ModelAttribute`, `@RequestBody`, `@RequestHeader`, `@Valid`, 和 `@RequestMapping`。使用这些注解可以轻松从HTTP请求中提取所需信息,例如URL参数、表单数据或者JSON请求体,并将其转换成Java对象以供进一步处理。
630 17
|
10月前
|
JSON API PHP
万年历API接口详解:精准获取指定日期信息
本文介绍接口盒子提供的万年历API,支持获取农历、节气、宜忌、星座等信息,具备完整的请求与返回示例,适用于黄历、日程管理等应用开发。
2534 0
|
算法 Java API
Java 方法注释:规范、实用和高质量的写法
本文深入探讨了如何编写高质量的 Java 方法注释
990 11
|
安全 IDE Java
Java常见规范及易忘点
遵循Java编程规范和注意易忘点是提高代码质量和可维护性的关键。通过规范的命名、格式、注释和合理的代码组织,可以让代码更加清晰和易于维护。同时,注意空指针检查、线程安全、集合框架和字符串操作等常见易忘点,可以减少程序错误,提高运行效率。结合单一职责原则、面向接口编程和合理的异常处理,能够编写出高质量的Java代码。希望本文能够帮助Java开发者提升编码水平,写出更高效、更可靠的代码。
241 2
|
安全 Java API
告别SimpleDateFormat:Java 8日期时间API的最佳实践
在Java开发中,处理日期和时间是一个基本而重要的任务。传统的`SimpleDateFormat`类因其简单易用而被广泛采用,但它存在一些潜在的问题,尤其是在多线程环境下。本文将探讨`SimpleDateFormat`的局限性,并介绍Java 8引入的新的日期时间API,以及如何使用这些新工具来避免潜在的风险。
320 5
|
Java 编译器 Android开发
java作业的提交规范与要求
java作业的提交规范与要求
274 0
|
安全 Java API
时间日期API(Date,SimpleDateFormat,Calendar)+java8新增日期API (LocalTime,LocalDate,LocalDateTime)
这篇文章介绍了Java中处理日期和时间的API,包括旧的日期API(Date、SimpleDateFormat、Calendar)和Java 8引入的新日期API(LocalTime、LocalDate、LocalDateTime)。文章详细解释了这些类/接口的方法和用途,并通过代码示例展示了如何使用它们。此外,还讨论了新旧API的区别,新API的不可变性和线程安全性,以及它们提供的操作日期时间的灵活性和简洁性。
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
JSON 前端开发 Java
【Java笔记+踩坑】SpringMVC基础
springmvc简介、入门案例、bean加载控制、PostMan工具的使用、普通和JSON和日期格式请求参数传递、响应JSON或jsp或文本、Rest风格
【Java笔记+踩坑】SpringMVC基础

热门文章

最新文章