1. 程式人生 > >關於Parse字串為時間一次被坑經歷

關於Parse字串為時間一次被坑經歷

在Java程式碼中發現一個bug,就是本來更新為時間的內容更新為一些奇怪的內容,比如20819這種形式,本來更新的時間都是近期不會超過一年,

為什麼會出現這種情況,非常奇怪,遂除錯下程式碼,跟蹤發現要匹配的字串內容和預想的日期格式不符合,程式碼處理這種情況是丟擲異常,

然後用今天的日期替代,結果沒成功,程式碼大概如下:

String dt = "20160901";
        SimpleDateFormat dateFm = new SimpleDateFormat("yyyyMM");
        Date strSuffix = null;
        try{
              strSuffix = dateFm.parse(dt);
        } catch
(Exception e){ strSuffix = new Date(); e.printStackTrace(); } 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);
    }
}