關於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, 也是將共享變量變為獨享,線程獨享肯定能比方法獨享在並發環境中能減少不少創建對象的開銷。如果對性能要求比較高的情況下,一般推薦使用這種方法。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM