• 关于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, 也是将共享变量变为独享,线程独享肯定能比方法独享在并发环境中能减少不少创建对象的开销。如果对性能要求比较高的情况下,一般推荐使用这种方法。

  • 相关阅读:
    Entity Framework 数据并发访问错误原因分析与系统架构优化
    项目中如何使用EF
    Entity Framework版本历史概览
    Entity Framework 6 预热、启动优化
    jQuery EasyUI Datagrid性能优化专题(转)
    jQuery EasyUI Datagrid VirtualScrollView视图简单分析
    用JS判断IE版本的代码
    【转】编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程
    【转】编写高质量代码改善C#程序的157个建议——建议55:利用定制特性减少可序列化的字段
    【转】编写高质量代码改善C#程序的157个建议——建议54:为无用字段标注不可序列化
  • 原文地址:https://www.cnblogs.com/seaspring/p/5855448.html
Copyright © 2020-2023  润新知