Joh*_*ith 3 java time android date simpledateformat
我有以下代码片段:
final Date d = format.parse(value);
LOGGER.debug("Compare:\nOriginal: {}, Format: {}, Result: {}", value, format.toPattern(), d);
return d;
Run Code Online (Sandbox Code Playgroud)
value 是来自json的String值,
format 是一个java.text.SimpleDateFormat,
d 是从中解析的日期 value
有时它工作正常,但有时会返回奇怪的日期.
logcat示例:
D/App: 20:14:47.309 com.example.backend.BackendHelper - Compare:
Original: 2016-09-16 13:45:00.000+0200, Format: yyyy-MM-dd HH:mm:ss.SSSZ, Result: Fri Jan 01 05:00:00 GMT+07:00 2016
D/App: 20:14:47.309 com.example.backend.BackendHelper - Compare:
Original: 2016-09-16 13:20:00.000+0200, Format: yyyy-MM-dd HH:mm:ss.SSSZ, Result: Fri Jan 01 18:20:00 GMT+07:00 2016
D/App: 20:14:47.338 com.example.backend.BackendHelper - Compare:
Original: 2016-09-16 15:20:00.000+0200, Format: yyyy-MM-dd HH:mm:ss.SSSZ, Result: Thu Jan 01 05:00:00 GMT+07:00 1970
如您所见,它返回不正确的日期(错误的年份或/和月份或/和小时),这些字符串具有完全相同的格式,并且仅按小时和分钟相互不同.
问题是:为什么?
您的格式模式是正确的.而且这里的区域设置不相关.
好吧,您还在问题中提供了输入,以便我们调查是否存在任何不可打印的字符.没有(和JSON不产生这样的废话 - 非常不可能).
因此,对于观察到的不可预测行为的解释是缺乏线程安全性. SimpleDateFormat不幸的是,它不是线程安全的(并且还有许多其他缺点).因此,只存储一个SimpleDateFormat静态类字段的实例确实很危险.
如何规避这种局限SimpleDateFormat?
SimpleDateFormat到ThreadLocal(更好)FastDateFormat(性能与ThreadLocale-solution相当,前缀"Fast"现在有点过时了)java.timeJava-8中包含的新时间库包的后端的Android改编),提供了一个不可变的解析器),例如:OffsetDateTime.parse(input, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSZ"))DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss.SSSZ").parseDateTime(input)ChronoFormatter.ofMomentPattern("yyyy-MM-dd HH:mm:ss.SSSZ", PatternType.CLDR, Locale.ROOT, ZonalOffset.UTC).parse(input)选择不可变的格式化程序/解析器无疑是在多线程环境中使用的最佳和最现代的方法.对于Android,Apache Commons和ThreetenABP库比Joda-Time或Time4A更快的替代品更紧凑.您必须自己评估哪些对您来说更重要,无论是大小还是性能(或者您需要的其他功能).