Java日期时间API系列35

Wesley13
• 阅读 913

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

Java日期时间API系列35

图中的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 比如: *

     * 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
     *
* @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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Wesley13 Wesley13
3年前
Java日期时间API系列34
  通过Java日期时间API系列9Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxkzhangsanx%2Fp%2F12110137.html)
Stella981 Stella981
3年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
Java日期时间API系列33
  从Java日期时间API系列10Jdk8中java.time包中的新的日期时间API类的DateTimeFormatter(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fxkzhangsanx%2Fp%2F12113489.html)中
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这