當前位置: 首頁>>編程語言>>正文


Java時間處理類SimpleDateFormat的parse和format方法的正確使用

SimpleDateFormat 是一個各種項目中使用頻度都很高的類,主要用於時間解析與格式化,頻繁使用的主要方法有parse和format.

parse方法:將字符串類型(java.lang.String)解析為日期類型(java.util.Date)
format方法:將日期類型(Date)數據格式化為字符串(String)

因為用的很多,所以在使用的時候需要關注更多細節,才能避免更多的坑。(踩得坑多了,才能成為一個會填坑的程序員。)

1. SimpleDateFormat是線程不安全的

官方文檔解釋如下(參見SimpleDateFormat):
Synchronization

Date formats are not synchronized. It is recommended to create separate format instances for each thread. 
If multiple threads access a format concurrently, it must be synchronized externally.

Date formats 是線程不安全的。推薦為每個線程創建單獨的format實例。如果多線程並發訪問同一個format實例,必須加同步操作。

錯誤的實現(前提是DateUtils.parseString()方法被多線程調用)

public class DateUtils {
    public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    // incorrect while be called by multiple threads
    public Date parseString(String datetime) throws Exception {
        return format.parse(datetime);
    }
}

正確實現:

class DateUtils {
    public static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    private static final Object LOCK = new Object();

    // OK
    public Date parseString(String datetime) throws Exception {
        synchronized (LOCK) {
            return format.parse(datetime);
        }
    }

    // OK
    public Date parseStringV2(String datetime) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return format.parse(datetime);
    }
}
2.SimpleDateFormat解析異常java.text.ParseException: Unparseable date

這個問題在stackoverflow上大概出現了1000+,在很多時候程序使用SimpleDateFormat都能正常執行,並不會報錯;但有時發現日誌出現
java.text.ParseException: Unparseable date: “2017-03-20 02:10″異常,為什麽還拋出這種異常呢?
先來看看代碼:

public Date parseStringV2(String datetime) throws Exception {
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return format.parse(datetime);
}

可以看到輸入時間為:2017-03-20 02:10, 解析的格式為:yyyy-MM-dd HH:mm:ss.
經過測試發現,當使用format方法將Date轉成String時,SimpleDateFormat可實例化為任意期望的時間格式;但是使用parse方法將String轉為Date時,SimpleDateFormat定義的格式與參數String的格式必須完全一致,不然就會出現Unparseable date。
另外,當使用Restful api服務時,後端Server與前端APP係統語言(本地環境)存在差異,也有可能出現“輸入時間為:2017-03-20 02:10, 解析的格式為:yyyy-MM-dd HH:mm,格式完全一致,parse偶爾也會解析出錯”,因為存在偶然不確定行,解決方案還持續分析中。

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/2736.html,未經允許,請勿轉載。