zoukankan      html  css  js  c++  java
  • 关于Parse字符串为时间一次被坑经历

       在Java代码中发现一个bug,就是本来更新为时间的内容更新为一些奇怪的内容,比如20819这种形式,本来更新的时间都是近期不会超过一年,

    为什么会出现这种情况,非常奇怪,遂调试下代码,跟踪发现要匹配的字符串内容和预想的日期格式不符合,代码处理这种情况是抛出异常,

    然后用今天的日期替代,结果没成功,代码大概如下:

     1         String dt = "20160901";
     2         SimpleDateFormat dateFm = new SimpleDateFormat("yyyyMM");
     3         Date strSuffix = null;
     4         try{
     5               strSuffix = dateFm.parse(dt);
     6         } catch(Exception e){
     7             strSuffix = new Date();
     8             e.printStackTrace();
     9         }
    10 
    11         System.out.println("result date:"+strSuffix.toLocaleString());

    按照本来的思路,应该是解析发生异常,然后时间为当前时间,结果打印为:2091-1-1 0:00:00

    可见,就算格式和实际的不符合,也不会抛出异常,仔细检查后发现,0901也当做月份来处理,即901,然后除12的话,等于75,再加上年份2016,

    刚好是2091年,这个确实和我们的预期不符,所以在做这类转化前最好确认下位数防止这种奇怪的现象。

    后来了解到SimpleDateFormat的生成开销比较大,尽量少用,而且不是线程安全的函数,如果网上提供了一个高效的用法:

    package com.peidasoft.dateformat;
    
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class ThreadLocalDateUtil {
        private static final String date_format = "yyyy-MM-dd HH:mm:ss";
        private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>(); 
     
        public static DateFormat getDateFormat()   
        {  
            DateFormat df = threadLocal.get();  
            if(df==null){  
                df = new SimpleDateFormat(date_format);  
                threadLocal.set(df);  
            }  
            return df;  
        }  
    
        public static String formatDate(Date date) throws ParseException {
            return getDateFormat().format(date);
        }
    
        public static Date parse(String strDate) throws ParseException {
            return getDateFormat().parse(strDate);
        }   
    }
    

      或者

    package com.peidasoft.dateformat;
    
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class ConcurrentDateUtil {
    
        private static ThreadLocal<DateFormat> threadLocal = new ThreadLocal<DateFormat>() {
            @Override
            protected DateFormat initialValue() {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            }
        };
    
        public static Date parse(String dateStr) throws ParseException {
            return threadLocal.get().parse(dateStr);
        }
    
        public static String format(Date date) {
            return threadLocal.get().format(date);
        }
    }
    

      说明:使用ThreadLocal, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。

  • 相关阅读:
    vue 客户端渲染和服务端渲染
    js 数组对象深拷贝
    vue template标签
    vue watch的高级用法
    js对象数组去重
    移动端触发touchend后阻止click事件
    重读JS(四)数据类型、作用域和内存问题
    重读JS(三)基本概念
    vue项目
    [vue问题解决]vue <router-link>在浏览器上点击失效(路由不跳转)
  • 原文地址:https://www.cnblogs.com/seaspring/p/5855448.html
Copyright © 2011-2022 走看看