OffsetDateTime 解决 纳秒 (ns) 时间格式转换

1,767 阅读2分钟

场景

一些时间精度高的设备,比如摄像头,可能时间会精确到纳秒,在 json 字符串数据将 createTime 字段

2021-09-28T09:21:08.710123123+08:00 转为 Date / LocalDateTime 时间格式时会失败, fastJson异常如下:

 Exception in thread "main" com.alibaba.fastjson.JSONException: For input string: "2021-09-28T09:21:08.710123123+08:00"
 ....
 Caused by: java.lang.NumberFormatException: For input string: "2021-09-28T09:21:08.710123123+08:00"    

时间精度达到 9 位,一般场景下会做舍弃后九尾, 也就是降低精度处理,转为常见的 ' yyyy-MM-dd HH:mm:ss '

时间格式。

OffsetDateTime类型

java8 中带偏移量、支持 UTC / Greenwich , 精度为纳秒(ns)。

 // 创建时间 
 private OffsetDateTime createTime; // dm8 - datetime支持OffsetDateTime插入

OffsetDateTime 专门接收 2021-09-28T09:21:08.710123123+08:00 格式数据, 经测试 fastjson 解析正常,

在达梦数据库测试下, 正常插入, 但是精度OffsetDateTime 9 变为数据库默认精度 6, 查询正常。

推荐场景:类型允许,该字段与其他时间格式类型交互少;否则,需要考虑时间类型转换成本

正则表达式 (推荐)

yyyy-MM-dd HH:mm:ss 格式,无非就是降低了精度,不要的精度使用正则表达式直接从 json 串截取替换掉。

 String jsonStr = "2021-09-28T09:21:08.710123123+08:00";
 // 匹配 .710123123
 String regex = "(\.)(\d{9})";
 System.out.println(jsonStr.replaceFirst(regex,"")); // 2021-09-28T09:21:08+08:00

String (不推荐)

jsonString -> OffsetDateTime(String) 格式化为 Date / LocalDateTime字符串格式 -> date

几乎哪里都要转换,garbage code .....

知道 OffsetDateTime 这个东西怎么使用就好了.....

     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private String createTime;
 ​
    public void setCreateTime(String createTime) {
        if (StrUtil.isBlank(createTime)) {
            Date date = new Date();
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            this.createTime = simpleDateFormat.format(date);
            return;
        }
        OffsetDateTime odt = OffsetDateTime.parse(createTime);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
        this.createTime = odt.format(dtf);
    }

解析

 public static void main(String[] args) {
         // example String (of ISO format)
         String input = "2021-09-28T09:21:08.710123123+08:00";
         // parse it (using a standard format implicitly)
         OffsetDateTime odt = OffsetDateTime.parse(input);
         // print the result
         System.out.println(odt); // 2021-09-28T09:21:08.710123123+08:00
 ​
         // if you want a different output, define a formatter
         DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
                 // use a desired pattern
                 "yyyy-MM-dd HH:mm:ss",
                 // and a desired locale (important for names)
                 Locale.ROOT);
         // print that
         System.out.println(odt.format(dtf)); // 2021-09-28 09:21:08
     }

\