Merge pull request #2288 from dklimkin/datefix

Additional date format and a hack for CEST
This commit is contained in:
Martin Fietz 2017-04-10 23:25:55 +02:00 committed by GitHub
commit e42a76219d
2 changed files with 37 additions and 18 deletions

View File

@ -101,4 +101,19 @@ public class DateUtilsTest extends AndroidTestCase {
assertEquals(expected, actual); assertEquals(expected, actual);
} }
public void testParseDateWithNoTimezonePadding() throws Exception {
GregorianCalendar exp = new GregorianCalendar(2017, 1, 22, 22, 28, 00);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis() + 2);
Date actual = DateUtils.parse("2017-02-22T14:28:00.002-08:00");
assertEquals(expected, actual);
}
public void testParseDateWithForCest() throws Exception {
GregorianCalendar exp = new GregorianCalendar(2017, 0, 28, 23, 00, 00);
exp.setTimeZone(TimeZone.getTimeZone("UTC"));
Date expected = new Date(exp.getTimeInMillis());
Date actual = DateUtils.parse("Sun, 29 Jan 2017 00:00:00 CEST");
assertEquals(expected, actual);
}
} }

View File

@ -22,35 +22,38 @@ public class DateUtils {
private static final TimeZone defaultTimezone = TimeZone.getTimeZone("GMT"); private static final TimeZone defaultTimezone = TimeZone.getTimeZone("GMT");
public static Date parse(final String input) { public static Date parse(final String input) {
if(input == null) { if (input == null) {
throw new IllegalArgumentException("Date must not be null"); throw new IllegalArgumentException("Date must not be null");
} }
String date = input.trim().replace('/', '-').replaceAll("( ){2,}+", " "); String date = input.trim().replace('/', '-').replaceAll("( ){2,}+", " ");
// CEST is widely used but not in the "ISO 8601 Time zone" list. Let's hack around.
date = date.replaceAll("CEST$", "+01:00");
// if datetime is more precise than seconds, make sure the value is in ms // if datetime is more precise than seconds, make sure the value is in ms
if(date.contains(".")) { if (date.contains(".")) {
int start = date.indexOf('.'); int start = date.indexOf('.');
int current = start+1; int current = start + 1;
while(current < date.length() && Character.isDigit(date.charAt(current))) { while (current < date.length() && Character.isDigit(date.charAt(current))) {
current++; current++;
} }
// even more precise than microseconds: discard further decimal places // even more precise than microseconds: discard further decimal places
if(current - start > 4) { if (current - start > 4) {
if(current < date.length()-1) { if (current < date.length() - 1) {
date = date.substring(0, start + 4) + date.substring(current); date = date.substring(0, start + 4) + date.substring(current);
} else { } else {
date = date.substring(0, start + 4); date = date.substring(0, start + 4);
} }
// less than 4 decimal places: pad to have a consistent format for the parser // less than 4 decimal places: pad to have a consistent format for the parser
} else if(current - start < 4) { } else if (current - start < 4) {
if(current < date.length()-1) { if (current < date.length() - 1) {
date = date.substring(0, current) + StringUtils.repeat("0", 4-(current-start)) + date.substring(current); date = date.substring(0, current) + StringUtils.repeat("0", 4 - (current - start)) + date.substring(current);
} else { } else {
date = date.substring(0, current) + StringUtils.repeat("0", 4-(current-start)); date = date.substring(0, current) + StringUtils.repeat("0", 4 - (current - start));
} }
} }
} }
String[] patterns = { final String[] patterns = {
"dd MMM yy HH:mm:ss Z", "dd MMM yy HH:mm:ss Z",
"dd MMM yy HH:mm Z", "dd MMM yy HH:mm Z",
"EEE, dd MMM yyyy HH:mm:ss Z", "EEE, dd MMM yyyy HH:mm:ss Z",
@ -76,6 +79,7 @@ public class DateUtils {
"yyyy-MM-dd'T'HH:mm:ss.SSS", "yyyy-MM-dd'T'HH:mm:ss.SSS",
"yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd'T'HH:mm:ssZ",
"yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ss'Z'",
"yyyy-MM-dd'T'HH:mm:ss.SSSZ",
"yyyy-MM-ddZ", "yyyy-MM-ddZ",
"yyyy-MM-dd" "yyyy-MM-dd"
}; };
@ -85,7 +89,7 @@ public class DateUtils {
parser.setTimeZone(defaultTimezone); parser.setTimeZone(defaultTimezone);
ParsePosition pos = new ParsePosition(0); ParsePosition pos = new ParsePosition(0);
for(String pattern : patterns) { for (String pattern : patterns) {
parser.applyPattern(pattern); parser.applyPattern(pattern);
pos.setIndex(0); pos.setIndex(0);
try { try {
@ -93,7 +97,7 @@ public class DateUtils {
if (result != null && pos.getIndex() == date.length()) { if (result != null && pos.getIndex() == date.length()) {
return result; return result;
} }
} catch(Exception e) { } catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e)); Log.e(TAG, Log.getStackTraceString(e));
} }
} }
@ -143,7 +147,7 @@ public class DateUtils {
} }
public static String formatAbbrev(final Context context, final Date date) { public static String formatAbbrev(final Context context, final Date date) {
if(date == null) { if (date == null) {
return ""; return "";
} }
GregorianCalendar cal = new GregorianCalendar(); GregorianCalendar cal = new GregorianCalendar();
@ -152,7 +156,7 @@ public class DateUtils {
cal.add(GregorianCalendar.DAY_OF_MONTH, 10); cal.add(GregorianCalendar.DAY_OF_MONTH, 10);
boolean withinLastYear = date.after(cal.getTime()); boolean withinLastYear = date.after(cal.getTime());
int format = android.text.format.DateUtils.FORMAT_ABBREV_ALL; int format = android.text.format.DateUtils.FORMAT_ABBREV_ALL;
if(withinLastYear) { if (withinLastYear) {
format |= android.text.format.DateUtils.FORMAT_NO_YEAR; format |= android.text.format.DateUtils.FORMAT_NO_YEAR;
} }
return android.text.format.DateUtils.formatDateTime(context, date.getTime(), format); return android.text.format.DateUtils.formatDateTime(context, date.getTime(), format);