I want to accept Arabic date in the query parameter
ex:
٢٠٢١-٠٧-٢٠
the English version of this date is 2021-07-20
I have found this soltion
DecimalStyle defaultDecimalStyle
= DateTimeFormatter.ISO_LOCAL_DATE.getDecimalStyle();
DateTimeFormatter arabicDateFormatter = DateTimeFormatter.ISO_LOCAL_DATE
.withDecimalStyle(defaultDecimalStyle.withZeroDigit('\u0660'));
String encodedArabicDateStr = "%D9%A2%D9%A0%D9%A1%D9%A9-%D9%A0%D9%A4-%D9%A1%D9%A5";
String arabicDateStr
= URLDecoder.decode(encodedArabicDateStr, StandardCharsets.UTF_8);
LocalDate date = LocalDate.parse(arabicDateStr, arabicDateFormatter);
System.out.println("Parsed date: " + date);
And it works as expected
now, in my Spring Boot application, I handle the LocalDate
with @DateTimeFormat
with pattern
@DateTimeFormat(pattern = "yyyy-MM-dd") val fromDate: LocalDate
How I can tell the Spring Boot to use a custom method to parse the date? The original problem is when someone send Arabic date the application it will crash with the below error:
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'dateRange' on field 'fromDate': rejected value [٢٠٢١-٠٧-٢٠];
codes [typeMismatch.dateRange.fromDate,typeMismatch.fromDate,typeMismatch.java.time.LocalDate,typeMismatch];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [dateRange.fromDate,fromDate];
arguments [];
default message [fromDate]];
default message [Failed to convert value of type 'java.lang.String[]' to required type 'java.time.LocalDate';
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.format.annotation.DateTimeFormat java.time.LocalDate] for value '٢٠٢١-٠٧-٢٠'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [٢٠٢١-٠٧-٢٠]]
I have tried:
You can create your own custom deserializer for LocalDate
which will contain the format field.
Creating of custom deserializer for LocalDate
public class CustomDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
DecimalStyle defaultDecimalStyle = DateTimeFormatter.ISO_LOCAL_DATE.getDecimalStyle();
DateTimeFormatter arabicDateFormatter = DateTimeFormatter.ISO_LOCAL_DATE.withDecimalStyle(defaultDecimalStyle.withZeroDigit('\u0660'));
String arabicDateStr = URLDecoder.decode(jsonParser.getText(), StandardCharsets.UTF_8);
return LocalDate.parse(arabicDateStr, arabicDateFormatter);
}
}
Using the custom deserializer for LocalDate
@JsonSerialize(using = CustomDateDeserializer.class)
private LocalDate fromDate;