mirror of
https://github.com/apache/struts.git
synced 2026-08-06 15:17:00 +00:00
Merge pull request #554 from gregh3269/More_localdatetime_support
Add basic LocalDateTime support WW-5175
This commit is contained in:
@@ -23,7 +23,9 @@ import java.lang.reflect.Member;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.time.temporal.TemporalAccessor;
|
||||
@@ -88,14 +90,15 @@ public class DateConverter extends DefaultTypeConverter {
|
||||
} catch (ParseException ignore) {
|
||||
}
|
||||
}
|
||||
} else if (java.time.LocalDateTime.class == toType) {
|
||||
} else if (java.time.LocalDateTime.class == toType || java.time.LocalDate.class == toType
|
||||
|| java.time.LocalTime.class == toType) {
|
||||
DateTimeFormatter dtf = null;
|
||||
TemporalAccessor check;
|
||||
TemporalAccessor check = null;
|
||||
DateTimeFormatter[] dfs = getDateTimeFormats(ActionContext.of(context), locale);
|
||||
|
||||
for (DateTimeFormatter df1 : dfs) {
|
||||
try {
|
||||
check = df1.parse(sa);
|
||||
check = df1.parseBest(sa, LocalDateTime::from, LocalDate::from, LocalTime::from);
|
||||
dtf = df1;
|
||||
if (check != null) {
|
||||
break;
|
||||
@@ -103,15 +106,20 @@ public class DateConverter extends DefaultTypeConverter {
|
||||
} catch (DateTimeParseException ignore) {
|
||||
}
|
||||
}
|
||||
if (dtf == null) {
|
||||
throw new TypeConversionException("Could not parse date");
|
||||
} else {
|
||||
try {
|
||||
try {
|
||||
if (dtf != null && check instanceof LocalDateTime) {
|
||||
return LocalDateTime.parse(sa, dtf);
|
||||
} catch (DateTimeParseException e) {
|
||||
throw new TypeConversionException("Could not parse date", e);
|
||||
} else if (dtf != null && check instanceof LocalDate) {
|
||||
return LocalDate.parse(sa, dtf);
|
||||
} else if (dtf != null && check instanceof LocalTime) {
|
||||
return LocalTime.parse(sa, dtf);
|
||||
} else {
|
||||
throw new TypeConversionException("Could not parse date");
|
||||
}
|
||||
} catch (DateTimeParseException e) {
|
||||
throw new TypeConversionException("Could not parse date", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// final fallback for dates without time
|
||||
@@ -179,7 +187,6 @@ public class DateConverter extends DefaultTypeConverter {
|
||||
private DateFormat[] getDateFormats(ActionContext context, Locale locale) {
|
||||
DateFormat globalDateFormat = null;
|
||||
String globalFormat = getGlobalDateString(context);
|
||||
//
|
||||
if (globalFormat != null) {
|
||||
globalDateFormat = new SimpleDateFormat(globalFormat, locale);
|
||||
}
|
||||
@@ -216,9 +223,23 @@ public class DateConverter extends DefaultTypeConverter {
|
||||
*/
|
||||
protected DateTimeFormatter[] getDateTimeFormats(ActionContext context, Locale locale) {
|
||||
|
||||
DateTimeFormatter df1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
DateTimeFormatter globalDateFormat = null;
|
||||
String globalFormat = getGlobalDateString(context);
|
||||
if (globalFormat != null) {
|
||||
globalDateFormat = DateTimeFormatter.ofPattern(globalFormat, locale);
|
||||
}
|
||||
|
||||
final DateTimeFormatter[] dateFormats = new DateTimeFormatter[] { df1 };
|
||||
DateTimeFormatter df1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
|
||||
DateTimeFormatter df2 = DateTimeFormatter.ISO_LOCAL_DATE;
|
||||
DateTimeFormatter df3 = DateTimeFormatter.ISO_LOCAL_TIME;
|
||||
|
||||
final DateTimeFormatter[] dateFormats;
|
||||
|
||||
if (globalDateFormat == null) {
|
||||
dateFormats = new DateTimeFormatter[] { df1, df2, df3 };
|
||||
} else {
|
||||
dateFormats = new DateTimeFormatter[] { globalDateFormat, df1, df2, df3 };
|
||||
}
|
||||
|
||||
return dateFormats;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,9 @@ import org.apache.struts2.conversion.TypeConversionException;
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@@ -45,7 +47,11 @@ public class DateConverterTest extends StrutsInternalTestCase {
|
||||
private final static String DATE_CONVERTED = "Fri Mar 20 00:00:00";
|
||||
private final static String INVALID_DATE = "99/99/2010";
|
||||
private final static String LOCALDATETIME_STR = "2020-03-20T00:00:00.000000";
|
||||
private final static String LOCALDATETIME1_STR = "12:00 AM Fri Mar 20, 2020";
|
||||
private final static String LOCALDATETIME_CONVERTED = "2020-03-20T00:00";
|
||||
private final static String LOCALDATE_STR = "2020-03-20";
|
||||
private final static String LOCALTIME_STR = "01:59:10";
|
||||
|
||||
private final static String INVALID_LOCALDATETIME = "2010-99-99T00:00";
|
||||
private final static String MESSAGE_PARSE_ERROR = "Could not parse date";
|
||||
private final static String MESSAGE_DEFAULT_CONSTRUCTOR_ERROR = "Couldn't create class null using default (long) constructor";
|
||||
@@ -53,8 +59,7 @@ public class DateConverterTest extends StrutsInternalTestCase {
|
||||
public void testSqlTimeType() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>())
|
||||
.withLocale(mxLocale);
|
||||
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
|
||||
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, TIME_01_59_10, Time.class);
|
||||
assertEquals("01:59:10", value.toString());
|
||||
@@ -63,10 +68,10 @@ public class DateConverterTest extends StrutsInternalTestCase {
|
||||
public void testSqlTimestampType() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>())
|
||||
.withLocale(mxLocale);
|
||||
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
|
||||
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, INPUT_TIME_STAMP_STR, Timestamp.class);
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, INPUT_TIME_STAMP_STR,
|
||||
Timestamp.class);
|
||||
assertEquals(RES_TIME_STAMP_STR, value.toString());
|
||||
}
|
||||
|
||||
@@ -78,9 +83,8 @@ public class DateConverterTest extends StrutsInternalTestCase {
|
||||
ValueStack stack = new StubValueStack();
|
||||
stack.push(new StubTextProvider(map));
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>())
|
||||
.withLocale(new Locale("es_MX", "MX"))
|
||||
.withValueStack(stack);
|
||||
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(new Locale("es_MX", "MX"))
|
||||
.withValueStack(stack);
|
||||
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, DATE_STR, Date.class);
|
||||
assertTrue(value.toString().startsWith(DATE_CONVERTED));
|
||||
@@ -94,9 +98,8 @@ public class DateConverterTest extends StrutsInternalTestCase {
|
||||
ValueStack stack = new StubValueStack();
|
||||
stack.push(new StubTextProvider(map));
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>())
|
||||
.withLocale(new Locale("es_MX", "MX"))
|
||||
.withValueStack(stack);
|
||||
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(new Locale("es_MX", "MX"))
|
||||
.withValueStack(stack);
|
||||
|
||||
try {
|
||||
converter.convertValue(context.getContextMap(), null, null, null, INVALID_DATE, Date.class);
|
||||
@@ -110,8 +113,7 @@ public class DateConverterTest extends StrutsInternalTestCase {
|
||||
public void testTypeConversionExceptionWhenUsingLongConstructor() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>())
|
||||
.withLocale(mxLocale);
|
||||
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
|
||||
|
||||
try {
|
||||
converter.convertValue(context.getContextMap(), null, null, null, INPUT_WHEN_LONG_CONSTRUCTOR_STR, null);
|
||||
@@ -125,46 +127,70 @@ public class DateConverterTest extends StrutsInternalTestCase {
|
||||
public void testLocalDateTimeType() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>());
|
||||
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATETIME_STR,
|
||||
LocalDateTime.class);
|
||||
assertTrue(value.toString().startsWith(LOCALDATETIME_CONVERTED));
|
||||
}
|
||||
|
||||
public void testLocalDateTime1Type() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put(org.apache.struts2.components.Date.DATETAG_PROPERTY, "yyyy-MM-dd");
|
||||
map.put(org.apache.struts2.components.Date.DATETAG_PROPERTY, "hh:mm a EEE MMM dd, yyyy");
|
||||
ValueStack stack = new StubValueStack();
|
||||
stack.push(new StubTextProvider(map));
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>())
|
||||
.withLocale(new Locale("es_MX", "MX"))
|
||||
.withValueStack(stack);
|
||||
ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale)
|
||||
.withValueStack(stack);
|
||||
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATETIME_STR, LocalDateTime.class);
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATETIME1_STR,
|
||||
LocalDateTime.class);
|
||||
assertTrue(value.toString().startsWith(LOCALDATETIME_CONVERTED));
|
||||
}
|
||||
|
||||
public void testLocalDateTimeTypeConversionExceptionWhenParseError() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
Map<String, String> map = new HashMap<>();
|
||||
map.put(org.apache.struts2.components.Date.DATETAG_PROPERTY, "yyyy-MM-dd");
|
||||
ValueStack stack = new StubValueStack();
|
||||
stack.push(new StubTextProvider(map));
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>())
|
||||
.withLocale(new Locale("es_MX", "MX"))
|
||||
.withValueStack(stack);
|
||||
ActionContext context = ActionContext.of(new HashMap<>());
|
||||
|
||||
try {
|
||||
converter.convertValue(context.getContextMap(), null, null, null, INVALID_LOCALDATETIME, LocalDateTime.class);
|
||||
converter.convertValue(context.getContextMap(), null, null, null, INVALID_LOCALDATETIME,
|
||||
LocalDateTime.class);
|
||||
fail("TypeConversionException expected - Conversion error occurred");
|
||||
} catch (Exception ex) {
|
||||
assertEquals(TypeConversionException.class, ex.getClass());
|
||||
assertEquals(MESSAGE_PARSE_ERROR, ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void testLocalDateType() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>());
|
||||
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATE_STR,
|
||||
LocalDate.class);
|
||||
assertTrue(value.toString().startsWith(LOCALDATE_STR));
|
||||
}
|
||||
|
||||
public void testLocalTimeType() {
|
||||
DateConverter converter = new DateConverter();
|
||||
|
||||
ActionContext context = ActionContext.of(new HashMap<>());
|
||||
|
||||
Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALTIME_STR,
|
||||
LocalTime.class);
|
||||
assertTrue(value.toString().startsWith(LOCALTIME_STR));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
//Due to JEP 252: Use CLDR Locale Data by Default
|
||||
// Due to JEP 252: Use CLDR Locale Data by Default
|
||||
DateFormat dFormat = DateFormat.getDateInstance(DateFormat.SHORT, mxLocale);
|
||||
if (dFormat.format(new Date()).contains("-")) { // Format when Java 9 or greater
|
||||
if (dFormat.format(new Date()).contains("-")) { // Format when Java 9 or greater
|
||||
INPUT_TIME_STAMP_STR = "2020-03-20 00:00:00.000";
|
||||
INPUT_WHEN_LONG_CONSTRUCTOR_STR = "2020-03-20";
|
||||
} else {// Format when Java 8 or lower
|
||||
|
||||
Reference in New Issue
Block a user