IllegalArgumentException Unknown pattern character ‘x’, when using SimpleDateFormat
代码如下:1
2
3
4
5try {
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX").parse("2019-05-14T19:00:11+08:00");
} catch (ParseException e) {
e.printStackTrace();
}
在Android 8.0运行没问题,但在5.1及以下会抛“IllegalArgumentException Unknown pattern character ‘x’, when using SimpleDateFormat”,如此看来基本可以认为是版本兼容问题
首先我们查找文档对于格式化定义,之前文章日期格式化YYYY日期错位中有提到Java中Date and Time Patterns,下面我们再看看Android中java.txt.SimpleDateFormat中的
Date and Time Patterns
Date and Time Patterns
Symbol | Meaning | Kind | Example |
---|---|---|---|
D | Day in year | Number | 189 |
E | Day of week | Text | E/EE/EEE:Tue,EEEE:Tuesday,EEEEE:T |
F | Day of week in month | Number | 2(2nd Wed inJuly) |
G | Era designator | Text | AD |
H | Hour in day (0-23) | Number | 0 |
K | Hour in am/pm (0-11) | Number | 0 |
L | stand-alone month | Text | L:1 LL:01 LLL:Jan LLLL:January LLLLL:J |
M | Month in year | Text | M:1 MM:01 MMM:Jan MMMM:January MMMMM:J |
S | fractional seconds | Number | 978 |
W | Week in month | Number | 2 |
Z | time zone (RFC 822) | time zone | Z/ZZ/ZZZ:-0800 ZZZZ:GMT-08:00 ZZZZZ:-08:00 |
a | Am/pm marker | Text | PM |
c | stand-alone day of week | Text | c/cc/ccc:Tue, cccc:Tuesday, ccccc:T |
d | Day in month | Number | 10 |
h | Hour in am/pm (1-12) | Number | 12 |
k | Hour in day (1-24) | Number | 24 |
m | Minute in hour | Number | 30 |
s | Second in minute | Number | 55 |
w | Week in year | Number | 27 |
y | Year | Number | yy:10 y/yyy/yyyy:2010 |
z | time zone | Time Zone | z/zz/zzz:PST zzzz:Pacific Standard Time |
‘ | escape for text | Delimiter | ‘Date=’:Date= |
‘ ‘ | single quote | Literal | ‘o’’clock’:o’clock |
从中我们看到X和Z都是time zone,改成Z即可。
Android中的SimpleDateFormat也是使用Java的api
Android 5.0开始采用了JDK 7,对应应该已经有X了,见SimpleDateFormat
但是我们从Android 22的源码中可以看到1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class SimpleDateFormat extends DateFormat {
private static final long serialVersionUID = 4774881970558875024L;
// 'L' and 'c' are ICU-compatible extensions for stand-alone month and stand-alone weekday.
static final String PATTERN_CHARS = "GyMdkHmsSEDFwWahKzZLc";
// The index of 'Z' in the PATTERN_CHARS string. This pattern character is supported by the RI,
// but has no corresponding public constant.
private static final int RFC_822_TIMEZONE_FIELD = 18;
// The index of 'L' (cf. 'M') in the PATTERN_CHARS string. This is an ICU-compatible extension
// necessary for correct localization in various languages (http://b/2633414).
private static final int STAND_ALONE_MONTH_FIELD = 19;
// The index of 'c' (cf. 'E') in the PATTERN_CHARS string. This is an ICU-compatible extension
// necessary for correct localization in various languages (http://b/2633414).
private static final int STAND_ALONE_DAY_OF_WEEK_FIELD = 20;
private String pattern;
private DateFormatSymbols formatData;
Android 281
2
3
4
5
6
7
8
9public class DateFormatSymbols implements Serializable, Cloneable {
...
/**
* Unlocalized date-time pattern characters. For example: 'y', 'd', etc.
* All locales use the same these unlocalized pattern characters.
*/
// Android-changed: Add 'c' (standalone day of week), 'b' (day period),
// 'B' (flexible day period)
static final String patternChars = "GyMdkHmsSEDFwWahKzZYuXLcbB";
重点:
static final String PATTERN_CHARS = “GyMdkHmsSEDFwWahKzZLc”;
static final String patternChars = “GyMdkHmsSEDFwWahKzZYuXLcbB”;
源码里可以看到导致问题原因,但是为何Android 22中的java代码与Java 7中不一致呢?