I have encountered an issue with date formatting on Android 6.0, Marshmallow. The code throwing the exception noted below is a pure-Java library (built separately) which my application uses for API requests ("the client"). The library is built with Java 1.6 if that is related...anyway, here is the code;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd E hh:mm aa", Locale.UK);
Date eventDate = dateFormat.parse(StringUtils.substring(record, 0, 23).trim());
...the record
has value;
2015-10-23 Fri 10:59 PM BST 3.60 meters
...which after "trimming" is;
2015-10-23 Fri 10:59 PM
yyyy-MM-dd E hh:mm aa
This code has worked since the good-old days of Froyo and is unit-tested. All that aside Marshmallow throws the exception;
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$2.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)
Offset "21" is the space after the '9' in 10:59. Can anyone explain this failure?
Update
Switched over to joda-time and it spat out a more informative error message. Here it is;
Invalid format ... is malformed at "PM"
...so, this is about the AM/PM aspect of the string trying to be parsed - back to the docs
The UK Locale appears to have had its definitions of "am" and "pm" altered.
In Marshmallow the UK Locale now has "am" represented as "a.m." and "pm" by "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());
I can't offer an explanation why, but the US Locale works with am/pm and the UK with a.m./p.m.
Edit
It appears that as part of the Locale updates in March 2015, the en_gb
locale had its am/pm definitions replaced. source diff
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With