• Java日期时间API系列35-----Jdk8中java.time包中的新的日期时间API类应用,微秒和纳秒等更精确的时间格式化和解析。


      通过Java日期时间API系列1-----Jdk7及以前的日期时间类中得知,Java8以前除了java.sql.Timestamp扩充纳秒,其他类最大只精确到毫秒;Java8 time包所有相关类都支持纳秒。下面是示意图:

    图中的nano 是 一秒钟包含的纳秒值,0到999999999。毫秒,微秒和纳秒都是通过这个值计算得到的。

    1.Timestamp格式化中的纳秒。

    java.sql.Timestamp.toString()方法中的格式为:

    格式化模板是:yyyy-mm-dd hh:mm:ss.fffffffff,这里的 fffffffff 指的是纳秒,但会将最后的0省略掉。比如:

    2020-05-23 17:06:30.0
    2020-05-23 17:06:30.272
    2020-05-23 17:06:30.27215
    2020-05-23 17:06:30.27215062

    2.Timestamp格式解析

    .

    /**
         * 解析Timestamp格式字符串为LocalDateTime  默认格式 yyyy-mm-dd hh:mm:ss.fffffffff 其中 fffffffff 纳秒,省略后面的0 比如:
         * <pre>
         * 2020-05-23 17:06:30.0
         * 2020-05-23 17:06:30.272
         * 2020-05-23 17:06:30.27215
         * 2020-05-23 17:06:30.27215062
         *</pre>
         * @param text
         * @return LocalDateTime
         */
        public static LocalDateTime parseTimestampStyleToLocalDateTime(String text){
            //预处理
            Objects.requireNonNull(text, "text");
            text=text.trim();
            if(!text.contains(".")){
                throw new DateTimeException("text is not supported! " + text);
            }
            
            //.分割成2部分,分别分析
            String[] textArr = text.split("\.");
            String main = textArr[0];
            String nanoOfSecond = textArr[1];
            int mainLen = main.length();
            int len = nanoOfSecond.length();
            if(mainLen != DateFormatPattern.YYYY_MM_DD_HH_MM_SS.length()){
                throw new DateTimeException("text is not supported! " + text);
            }
            if(len>9){
                throw new DateTimeException("text is not supported! " + text);
            }
            
            //纳秒部分补0
            StringBuilder sb = new StringBuilder();
            for(int i=0;i<9-len;i++){
                sb.append("0");
            }
            nanoOfSecond = nanoOfSecond+sb.toString();
            text = main+"."+nanoOfSecond;
            
            //使用yyyy-MM-dd HH:mm:ss.SSSSSSSSS 标准格式解析
            return parseToLocalDateTime(text, DateTimeFormatterUtil.YYYY_MM_DD_HH_MM_SS_SSSSSSSSS_FMT);
        }

    测试:

      /**
         * 含纳秒Timestamp时间格式解析
         */
        @Test
        public void parseTimestampStyleTest(){
            
            Date date = DateTimeFormatterUtil.smartParseToDate("2020-05-23 17:06:30");
            
            Date date2 = DateTimeFormatterUtil.parseTimestampStyleToDate("2020-05-23 17:06:30.0");
            
            Date date3 = DateTimeFormatterUtil.parseTimestampStyleToDate("2020-05-23 17:06:30.0");
            
            Assert.assertEquals(date, date2);
            Assert.assertEquals(date2, date3);
            
            LocalDateTime localDateTime1 = DateTimeFormatterUtil.smartParseToLocalDateTime("2020-05-23 17:06:30.272150");
            
            LocalDateTime localDateTime2 = DateTimeFormatterUtil.smartParseToLocalDateTime("2020-05-23 17:06:30.27215");
            Assert.assertEquals(localDateTime1, localDateTime2);
        }

    3.微秒和纳秒的格式化和解析

     // ==================================yyyy-MM-dd HH:mm:ss.SSSSSS 相关Pattern==================================    
        
        /**
         * yyyy-MM-dd HH:mm:ss.SSSSSS 比如:2020-05-23 17:06:30.272150
         */
        public static final String YYYY_MM_DD_HH_MM_SS_SSSSSS = "yyyy-MM-dd HH:mm:ss.SSSSSS";
        
        
        
        // ==================================yyyy-MM-dd HH:mm:ss.SSSSSSSSS 相关Pattern==================================    
        
        /**
         * yyyy-MM-dd HH:mm:ss.SSSSSSSSS 比如:2020-05-23 17:06:30.272150620
         */
        public static final String YYYY_MM_DD_HH_MM_SS_SSSSSSSSS = "yyyy-MM-dd HH:mm:ss.SSSSSSSSS";    

    (1)格式化

      /**
         * 含纳秒时间格式化
         */
        @Test
        public void formatTimeWithNanoTest(){
            LocalDateTime localDateTime = DateTimeFormatterUtil.smartParseToLocalDateTime("2020-05-23T17:06:30.272150620+08:00");
            //时间格式化
            Assert.assertEquals("17:06:30.272", DateTimeFormatterUtil.format(localDateTime, DateTimeFormatterUtil.HH_MM_SS_SSS_FMT));
            Assert.assertEquals("17:06:30.272150", DateTimeFormatterUtil.format(localDateTime, DateTimeFormatterUtil.HH_MM_SS_SSSSSS_FMT));
            Assert.assertEquals("17:06:30.272150620", DateTimeFormatterUtil.format(localDateTime, DateTimeFormatterUtil.HH_MM_SS_SSSSSSSSS_FMT));
            
            //日期时间格式化
            Assert.assertEquals("2020-05-23 17:06:30.272150", DateTimeFormatterUtil.format(localDateTime, DateTimeFormatterUtil.YYYY_MM_DD_HH_MM_SS_SSSSSS_FMT));
            Assert.assertEquals("2020-05-23 17:06:30.272150620", DateTimeFormatterUtil.format(localDateTime, DateTimeFormatterUtil.YYYY_MM_DD_HH_MM_SS_SSSSSSSSS_FMT));
    
            //ISO日期时间格式化
            Assert.assertEquals("2020-05-23T17:06:30.272150620+0800", DateTimeFormatterUtil.format(localDateTime, DateTimeFormatterUtil.YYYY_MM_DD_T_HH_MM_SS_SSSSSSSSS_Z_FMT));
            Assert.assertEquals("2020-05-23T17:06:30.272150620+08:00", DateTimeFormatterUtil.format(localDateTime, DateTimeFormatterUtil.YYYY_MM_DD_T_HH_MM_SS_SSSSSSSSS_XXX_Z_FMT));
        }

    (2)解析

     /**
         * 含纳秒时间格式解析
         */
        @Test
        public void parseTimeWithNanoTest(){
            LocalDateTime localDateTime1 = DateTimeFormatterUtil.smartParseToLocalDateTime("2020-05-23T17:06:30.272150620+08:00");
            
            LocalDateTime localDateTime2 = DateTimeFormatterUtil.smartParseToLocalDateTime("2020-05-23T17:06:30.272150+08:00");
            
            LocalDateTime localDateTime3 = DateTimeFormatterUtil.smartParseToLocalDateTime("2020-05-23T17:06:30.272+08:00");
            
            Assert.assertTrue(localDateTime3.isBefore(localDateTime2));
            
            Assert.assertTrue(localDateTime2.isBefore(localDateTime1));
        }

    4.LocalDateTime转Date会精度丢失,丢失毫秒以后部分。

    因为Date只精确到毫秒,下面是转换方法:DateTimeConverterUtil类中

        /**
         * LocalDateTime转Date
         * @param localDateTime
         * @return Date
         */
        public static Date toDate(LocalDateTime localDateTime) {
            Objects.requireNonNull(localDateTime, "localDateTime");
            return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
        }
    Date from(Instant instant)方法:
        public static Date from(Instant instant) {
            try {
                return new Date(instant.toEpochMilli());
            } catch (ArithmeticException ex) {
                throw new IllegalArgumentException(ex);
            }
        }

     核心部分:new Date(instant.toEpochMilli()); 创建Date只使用了Instant的时间戳部分 instant.toEpochMilli()。只到毫秒。

    源代码地址:https://github.com/xkzhangsan/xk-time

  • 相关阅读:
    [zz][openstack swift]0 swift介绍
    [zz]/usr、/var和/etc目录
    [zz]使用 watchdog 构建高可用性的 Linux 系统及应用
    [zz]sheep dog的readme
    [zz] Consistent Hashing Ring
    [zz]为什么这些死脑筋们在用 VI ?
    libvirt 网络
    [zz]libcapng
    libvirt 创建的文件
    电商购物网站如何调用第三方支付平台(支付宝,财付通,盛付通等)
  • 原文地址:https://www.cnblogs.com/xkzhangsanx/p/13155311.html
Copyright © 2020-2023  润新知