Date Parse Exception in Android for input Mon, 11 Sep 2023 15:49:32 GMT

209 Views Asked by At
 fun calculateAge(dateString: String): String {
        val dateFormat = SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z")
        dateFormat.timeZone = TimeZone.getTimeZone("GMT")
        val inputDate = dateFormat.parse(dateString)
        val currentCalendar = Calendar.getInstance()
        val inputCalendar = Calendar.getInstance()
        inputCalendar.time = inputDate
        val years = currentCalendar.get(Calendar.YEAR) - inputCalendar.get(Calendar.YEAR)
        val months = currentCalendar.get(Calendar.MONTH) - inputCalendar.get(Calendar.MONTH)
        val days = currentCalendar.get(Calendar.DAY_OF_MONTH) - inputCalendar.get(Calendar.DAY_OF_MONTH)

        return when {
            years > 0 -> "$years years "
            months > 0 -> "$months months"
            else -> "$days days"
        }
    }

My Input of date is : Mon, 11 Sep 2023 15:49:32 GMT

i am getting this Exception : java.text.ParseException: Unparseable date: "Mon, 11 Sep 2023 15:49:32 GMT"

this is piece of code using this i am trying to calculate age its working fine till API level 33 in android but when i trying to run code using api level 34 i am getting parse exception in android can any one please help me how to fix this issue .

1

There are 1 best solutions below

1
Arvind Kumar Avinash On

java.time

In March 2014, the modern Date-Time API supplanted the legacy date-time API. Since then, it has been strongly recommended to switch to java.time, the modern date-time API.

Your date-time string is compliant with DateTimeFormatter.RFC_1123_DATE_TIME format. You can get the date part (LocalDate) out of the OffsetDateTime, obtained as a result of parsing the given date-time string using this DateTimeFormatter.

Get the current LocalDate at UTC and then find the period between these two dates using Period#between.

var strDateTime = "Mon, 11 Sep 2023 15:49:32 GMT";
var dateFrom = OffsetDateTime.parse(strDateTime, DateTimeFormatter.RFC_1123_DATE_TIME)
               .toLocalDate();
var dateUntil = LocalDate.now(ZoneOffset.UTC);
var period = Period.between(dateFrom, dateUntil);
System.out.println(period);

// Formatted
System.out.println(formattedPeriod(period));

where formattedPeriod(Period) is a function returning a String formatted in your desired manner.

String formattedPeriod(Period period) {
    var years = period.getYears();
    var months = period.getMonths();

    return years > 0 ? years + " years" : months > 0 ? months + " months" : period.getDays() + " days";
}

Output:

P27D
27 days

Online Demo

Learn about the modern date-time API from Trail: Date Time

Note: My area of expertise is Java and therefore I have written the code using Java language. Kotlin supports running Java code as it is. A Kotlin programmer can easily translate a Java code into the corresponding Kotlin code. Moreover, most part of my code can be reused as it is in the corresponding Kotlin program.

Update

Since your date-time string is in GMT/UTC, I have used LocalDate.now(ZoneOffset.UTC) to get the current LocalDate in GMT/UTC i.e. the key is to get the LocalDate using the same time zone offset as your data-time string.

As commented by Ole V.V., you can explicitly apply a time zone offset to the parsed date-time and the current LocalDate. He has also provided a link to the solution in Kotlin using his approach. Here is the link to the code in Java using his approach.