Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accept Arabic date as query parameter in Spring Boot

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:

  • update request values by filter but it does not work.
  • FormattingConversionService like this sample.
like image 745
Mohamd Ali Avatar asked Dec 07 '25 07:12

Mohamd Ali


1 Answers

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;
like image 103
Jonathan JOhx Avatar answered Dec 08 '25 21:12

Jonathan JOhx