Android Marshmallow 中的 SimpleDateFormat 行为更改
SimpleDateFormat behaviour change in Android Marshmallow
我在 Android 6.0 Marshmallow 上遇到了日期格式问题。下面提到的引发异常的代码是一个纯 Java 库(单独构建),我的应用程序将其用于 API 请求 ("the client")。如果相关的话,库是用 Java 1.6 构建的……无论如何,这是代码;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd E hh:mm aa", Locale.UK);
Date eventDate = dateFormat.parse(StringUtils.substring(record, 0, 23).trim());
...record
有价值;
2015-10-23 Fri 10:59 PM BST 3.60 meters
..."trimming" 之后是;
2015-10-23 Fri 10:59 PM
yyyy-MM-dd E hh:mm aa
这段代码自 Froyo 的美好时光以来就一直有效,并且经过了单元测试。除了 Marshmallow 之外的所有内容都会抛出异常;
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: SynchroniseTidePosition.doInBackground
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: java.text.ParseException: Unparseable date: "2015-10-23 Fri 10:59 PM" (at offset 21)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.text.DateFormat.parse(DateFormat.java:579)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.oceanlife.rover.handler.XTideParser.parseResponse(XTideParser.java:69)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.brantapps.oceanlife.task.SynchroniseTidePosition.doInBackground(SynchroniseTidePosition.java:107)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.brantapps.oceanlife.task.SynchroniseTidePosition.doInBackground(SynchroniseTidePosition.java:43)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at android.os.AsyncTask.call(AsyncTask.java:295)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.lang.Thread.run(Thread.java:818)
偏移量“21”是 10:59 中“9”之后的 space。谁能解释这个失败?
更新
切换到 joda-time,它吐出一条信息更丰富的错误消息。在这里;
Invalid format ... is malformed at "PM"
...所以,这是关于试图解析的字符串的 AM/PM 方面 - 回到 the docs
英国语言环境似乎更改了 "am" 和 "pm" 的定义。
在 Marshmallow 中,英国语言环境现在 "am" 表示为 "a.m.","pm" 表示为 "p.m."
String record = "2015-10-23 Fri 10:59 p.m. BST 3.60 meters"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd E hh:mm aa", Locale.UK);
// note the length is 25 now, not 23...
Date eventDate = dateFormat.parse(StringUtils.substring(record, 0, 25).trim());
我无法解释原因,但美国地区适用于 am/pm,英国地区适用于 a.m./p.m.
编辑
看来,作为 2015 年 3 月区域设置更新的一部分,en_gb
区域设置已替换其 am/pm 定义。 source diff
我在 Android 6.0 Marshmallow 上遇到了日期格式问题。下面提到的引发异常的代码是一个纯 Java 库(单独构建),我的应用程序将其用于 API 请求 ("the client")。如果相关的话,库是用 Java 1.6 构建的……无论如何,这是代码;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd E hh:mm aa", Locale.UK);
Date eventDate = dateFormat.parse(StringUtils.substring(record, 0, 23).trim());
...record
有价值;
2015-10-23 Fri 10:59 PM BST 3.60 meters
..."trimming" 之后是;
2015-10-23 Fri 10:59 PM
yyyy-MM-dd E hh:mm aa
这段代码自 Froyo 的美好时光以来就一直有效,并且经过了单元测试。除了 Marshmallow 之外的所有内容都会抛出异常;
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: SynchroniseTidePosition.doInBackground
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: java.text.ParseException: Unparseable date: "2015-10-23 Fri 10:59 PM" (at offset 21)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.text.DateFormat.parse(DateFormat.java:579)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.oceanlife.rover.handler.XTideParser.parseResponse(XTideParser.java:69)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.brantapps.oceanlife.task.SynchroniseTidePosition.doInBackground(SynchroniseTidePosition.java:107)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at com.brantapps.oceanlife.task.SynchroniseTidePosition.doInBackground(SynchroniseTidePosition.java:43)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at android.os.AsyncTask.call(AsyncTask.java:295)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
10-23 21:01:56.816 4091-4110/com.oceanlife E/ParseException: at java.lang.Thread.run(Thread.java:818)
偏移量“21”是 10:59 中“9”之后的 space。谁能解释这个失败?
更新
切换到 joda-time,它吐出一条信息更丰富的错误消息。在这里;
Invalid format ... is malformed at "PM"
...所以,这是关于试图解析的字符串的 AM/PM 方面 - 回到 the docs
英国语言环境似乎更改了 "am" 和 "pm" 的定义。
在 Marshmallow 中,英国语言环境现在 "am" 表示为 "a.m.","pm" 表示为 "p.m."
String record = "2015-10-23 Fri 10:59 p.m. BST 3.60 meters"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd E hh:mm aa", Locale.UK);
// note the length is 25 now, not 23...
Date eventDate = dateFormat.parse(StringUtils.substring(record, 0, 25).trim());
我无法解释原因,但美国地区适用于 am/pm,英国地区适用于 a.m./p.m.
编辑
看来,作为 2015 年 3 月区域设置更新的一部分,en_gb
区域设置已替换其 am/pm 定义。 source diff