当前位置: 首页>>编程语言>>正文


Java时间处理类SimpleDateFormat的parse和format方法的正确使用

yangfan 编程语言 , , , , 去评论

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/article/2736.html,未经允许,请勿转载。