Kotlin DateTimeParseException
Asked Answered
J

2

2

Getting date from https://api.spacexdata.com/v3/launches This date have format: 2006-03-25T10:30:00+12:00. I want convert it to "dd, mm, yyyy", but always getting error: "java.time.format.DateTimeParseException: Text '2006-03-25T10:30:00+12:00' could not be parsed, unparsed text found at index 10"

my code:

val formatter = DateTimeFormatter.ofPattern("dd, mm, yyyy", Locale.US)
val myDate = LocalDate.parse(launchDate, formatter)

var launchDateConverted: String=  myDate.toString()

i getting data at String, then i convert it to date for formatting, and after i converting date back to string thats to display at UI. i used different methods, but cannot find the correct way. My current locale is "RU".

Judoka answered 26/1, 2021 at 20:29 Comment(0)
H
4
  1. Your formatter does not match the input format. Basically you need two formatters: one for input and one for output.
  2. The format "dd, mm, yyyy" is wrong: mm stands for minute of hour, not for month. You should use "dd, MM, yyyy".
val launchDate = "2006-03-25T10:30:00+12:00"

val inputFormatter = DateTimeFormatter.ISO_DATE_TIME
val myDate = LocalDate.parse(launchDate, inputFormatter)

val outputFormatter = DateTimeFormatter.ofPattern("dd, MM, yyyy", Locale.US)
println(outputFormatter.format(myDate))
Helmick answered 26/1, 2021 at 21:16 Comment(0)
S
8

You do not need any formatter to parse your input string

You input string, 2006-03-25T10:30:00+12:00 is already in the default format used by OffsetDateTime#parse and therefore, you do not need to use a formatter explicitly in order to parse your input date-time string.

m specifies the minute while M specifies the month

You have wrongly used m for the month for which the symbol is M. Check the documentation page to learn more about these symbols.

Prefer u to y

y specifies the year-of-era (era is specified as AD or BC) and is always a positive number whereas u specifies the year which is a signed (+/-) number. Normally, we do not use + sign to write a positive number but we always specify a negative number with a - sign. The same rule applies for a year. As long as you are going to use a year of the era, AD (which is mostly the case), both, y and u will give you the same number. However, the difference occurs when you use a year of the era, BC e.g. the year-of-era, 1 BC is specified as year, 0; the year-of-era, 2 BC is specified as year, -1 and so on. You can understand it better with the following demo:

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class Testing {
    public static void main(String[] args) {
        System.out.println(LocalDate.of(-1, 1, 1).format(DateTimeFormatter.ofPattern("u M d")));
        System.out.println(LocalDate.of(-1, 1, 1).format(DateTimeFormatter.ofPattern("y M d")));
        System.out.println(LocalDate.of(-1, 1, 1).format(DateTimeFormatter.ofPattern("yG M d")));

        System.out.println();

        System.out.println(LocalDate.of(0, 1, 1).format(DateTimeFormatter.ofPattern("u M d")));
        System.out.println(LocalDate.of(0, 1, 1).format(DateTimeFormatter.ofPattern("y M d")));
        System.out.println(LocalDate.of(0, 1, 1).format(DateTimeFormatter.ofPattern("yG M d")));

        System.out.println();

        System.out.println(LocalDate.of(1, 1, 1).format(DateTimeFormatter.ofPattern("u M d")));
        System.out.println(LocalDate.of(1, 1, 1).format(DateTimeFormatter.ofPattern("y M d")));
        System.out.println(LocalDate.of(1, 1, 1).format(DateTimeFormatter.ofPattern("yG M d")));
    }
}

Output:

-1 1 1
2 1 1
2BC 1 1

0 1 1
1 1 1
1BC 1 1

1 1 1
1 1 1
1AD 1 1

Note: I've used Java to demonstrate the solution but it will also work in Kotlin.

The final solution:

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        OffsetDateTime odt = OffsetDateTime.parse("2006-03-25T10:30:00+12:00");
        System.out.println(odt);

        // Format it into the desired pattern
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd, MM, uuuu", Locale.US);
        String formatted = dtf.format(odt);
        System.out.println(formatted);
    }
}

Output:

2006-03-25T10:30+12:00
25, 03, 2006

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

Subzero answered 27/1, 2021 at 21:58 Comment(2)
Recommend using BCE (Before Common or Current era) and CE (Common Era) over BC (before Christ) and AD (after death). BC/AD is still in contention over what actual historical dates are involved, while CE/BCE is set and also preserves religious neutrality.Jampacked
@LabGecko, Thanks for adding this useful information.Subzero
H
4
  1. Your formatter does not match the input format. Basically you need two formatters: one for input and one for output.
  2. The format "dd, mm, yyyy" is wrong: mm stands for minute of hour, not for month. You should use "dd, MM, yyyy".
val launchDate = "2006-03-25T10:30:00+12:00"

val inputFormatter = DateTimeFormatter.ISO_DATE_TIME
val myDate = LocalDate.parse(launchDate, inputFormatter)

val outputFormatter = DateTimeFormatter.ofPattern("dd, MM, yyyy", Locale.US)
println(outputFormatter.format(myDate))
Helmick answered 26/1, 2021 at 21:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.