Allow date format to supported group of built-in patterns

Until now 'named dates' like dateOptionalTime could not be used as a group
of dates. This patch allows it to group it arbitrarily like this:

* yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||dateOptionalTime
* dateOptionalTime||yyyy/MM/dd HH:mm:ss||yyyy/MM/dd
* yyyy/MM/dd HH:mm:ss||dateOptionalTime||yyyy/MM/dd
* date_time||date_time_no_millis

Closes #2132
This commit is contained in:
Alexander Reelsen 2013-06-10 10:55:45 +02:00 committed by Simon Willnauer
parent 015d820e53
commit 9d3e34b9f9
2 changed files with 67 additions and 13 deletions

View File

@ -41,6 +41,13 @@ public class Joda {
* Parses a joda based pattern, including some named ones (similar to the built in Joda ISO ones).
*/
public static FormatDateTimeFormatter forPattern(String input, Locale locale) {
if (Strings.hasLength(input)) {
input = input.trim();
}
if (input == null || input.length() == 0) {
throw new IllegalArgumentException("No date pattern provided");
}
DateTimeFormatter formatter;
if ("basicDate".equals(input) || "basic_date".equals(input)) {
formatter = ISODateTimeFormat.basicDate();
@ -126,20 +133,33 @@ public class Joda {
formatter = ISODateTimeFormat.yearMonth();
} else if ("yearMonthDay".equals(input) || "year_month_day".equals(input)) {
formatter = ISODateTimeFormat.yearMonthDay();
} else {
String[] formats = Strings.delimitedListToStringArray(input, "||");
if (formats == null || formats.length == 1) {
formatter = DateTimeFormat.forPattern(input);
} else {
} else if (Strings.hasLength(input) && input.contains("||")) {
String[] formats = Strings.delimitedListToStringArray(input, "||");
DateTimeParser[] parsers = new DateTimeParser[formats.length];
for (int i = 0; i < formats.length; i++) {
parsers[i] = DateTimeFormat.forPattern(formats[i]).withZone(DateTimeZone.UTC).getParser();
if (formats.length == 1) {
formatter = forPattern(input, locale).parser();
} else {
DateTimeFormatter dateTimeFormatter = null;
for (int i = 0; i < formats.length; i++) {
DateTimeFormatter currentFormatter = forPattern(formats[i], locale).parser();
if (dateTimeFormatter == null) {
dateTimeFormatter = currentFormatter;
}
parsers[i] = currentFormatter.getParser();
}
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder().append(dateTimeFormatter.withZone(DateTimeZone.UTC).getPrinter(), parsers);
formatter = builder.toFormatter();
}
DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
.append(DateTimeFormat.forPattern(formats[0]).withZone(DateTimeZone.UTC).getPrinter(), parsers);
formatter = builder.toFormatter();
} else {
try {
formatter = DateTimeFormat.forPattern(input);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid format: [" + input + "]: " + e.getMessage(), e);
}
}
return new FormatDateTimeFormatter(input, formatter.withZone(DateTimeZone.UTC), locale);
}

View File

@ -30,7 +30,10 @@ import org.testng.annotations.Test;
import java.util.Date;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.testng.AssertJUnit.fail;
/**
*
@ -145,10 +148,41 @@ public class SimpleJodaTests {
public void testMultipleFormats() {
FormatDateTimeFormatter formatter = Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd");
long millis = formatter.parser().parseMillis("1970/01/01 00:00:00");
millis = formatter.parser().parseMillis("1970/01/01");
// System.out.println("" + millis);
assertThat("1970/01/01 00:00:00", is(formatter.printer().print(millis)));
}
System.out.println(formatter.printer().print(millis));
@Test
public void testMultipleDifferentFormats() {
FormatDateTimeFormatter formatter = Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd");
String input = "1970/01/01 00:00:00";
long millis = formatter.parser().parseMillis(input);
assertThat(input, is(formatter.printer().print(millis)));
Joda.forPattern("yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||dateOptionalTime");
Joda.forPattern("dateOptionalTime||yyyy/MM/dd HH:mm:ss||yyyy/MM/dd");
Joda.forPattern("yyyy/MM/dd HH:mm:ss||dateOptionalTime||yyyy/MM/dd");
Joda.forPattern("date_time||date_time_no_millis");
Joda.forPattern(" date_time || date_time_no_millis");
}
@Test
public void testInvalidPatterns() {
expectInvalidPattern("does_not_exist_pattern", "Invalid format: [does_not_exist_pattern]: Illegal pattern component: o");
expectInvalidPattern("OOOOO", "Invalid format: [OOOOO]: Illegal pattern component: OOOOO");
expectInvalidPattern(null, "No date pattern provided");
expectInvalidPattern("", "No date pattern provided");
expectInvalidPattern(" ", "No date pattern provided");
expectInvalidPattern("||date_time_no_millis", "No date pattern provided");
expectInvalidPattern("date_time_no_millis||", "No date pattern provided");
}
private void expectInvalidPattern(String pattern, String errorMessage) {
try {
Joda.forPattern(pattern);
fail("Pattern " + pattern + " should have thrown an exception but did not");
} catch (IllegalArgumentException e) {
assertThat(e.getMessage(), containsString(errorMessage));
}
}
@Test