0

How to convert this string into instant: String date = "Fri Sep 30 00:00:00 IST 2022";

Exception:

java.time.format.DateTimeParseException: Text 'Fri Sep 30 00:00:00 IST 2022' could not be parsed at index 0
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2046)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948)
    at java.base/java.time.LocalDate.parse(LocalDate.java:428)

In DB it is saved in this format

ISODate("2022-09-29T18:30:00.000Z")

But while debugging in IDE it is coming in string format like this: "Fri Sep 30 00:00:00 IST 2022" Now I want to convert it back to instant

I tried in this way:

DateTimeFormatter DATE_FORMAT_RULE = DateTimeFormatter.ofPattern("MM/dd/yyyy");
String date = "Fri Sep 30 00:00:00 IST 2022";
Instant instant = LocalDate.parse(date, DATE_FORMAT_RULE)
                           .atStartOfDay()
                           .toInstant(ZoneOffset.UTC);
10
  • Can you show how you have tried to parse that String? Commented Sep 30, 2022 at 6:43
  • 1
    @deHaar I mentioned what I tried Commented Sep 30, 2022 at 6:53
  • 1
    @deHaar It is working as expected with this pattern. Thanks Commented Sep 30, 2022 at 7:35
  • 2
    but maybe it is just wrong to get the date from database as a String or convert it to a String (but the relevant code is not included in the question) Commented Sep 30, 2022 at 7:54
  • 2
    Side note: The date format you use is quite dangerous for parsing. A recent change in CLDR now uses e.g. "Sept" for September in Locale.UK, see bugs.openjdk.org/browse/JDK-8256837 and unicode-org.github.io/cldr-staging/charts/38/delta/…. Better avoid parsing text-based date formats, if possible. Commented Sep 30, 2022 at 9:10

3 Answers 3

2

The pattern you are using does not match the one of the String. Your pattern cannot parse a two-digit month first because the String starts with an abbreviated day of week, whose abbreviation even depends on the Locale, which you haven't specified, so it will take the system default.

However, you can try to parse it with a different pattern, but I don't think it will get you the desired result… Try DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu", Locale.ENGLISH) instead of your DateTimeFormatter.ofPattern("MM/dd/yyyy") and see the result. On my machine, it assumes IST to be Iceland Standard Time!

See this example:

public static void main(String[] args) {
    // example String
    String toBeParsed = "Fri Sep 30 00:00:00 IST 2022";
    // first formatter: tries to parse "IST" as ZONE TEXT
    DateTimeFormatter dtfZ = new DateTimeFormatterBuilder()
                                    .appendPattern("EEE MMM dd HH:mm:ss")
                                    .appendLiteral(' ')
                                    .appendZoneText(TextStyle.SHORT)
                                    .appendLiteral(' ')
                                    .appendPattern("uuuu")
                                    .toFormatter(Locale.ENGLISH);
    // second formatter: tries to parse "IST" as ZONE NAME
    DateTimeFormatter dtfz = DateTimeFormatter.ofPattern(
                                    "EEE MMM dd HH:mm:ss z uuuu",
                                    Locale.ENGLISH
                            );
    // parse to a ZonedDateTime with the first formatter
    ZonedDateTime zdt = ZonedDateTime.parse(toBeParsed, dtfZ);
    // print the result
    System.out.println("ZonedDateTime: "
                    + zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // parse to a ZonedDateTime with the second formatter
    ZonedDateTime zdt2 = ZonedDateTime.parse(toBeParsed, dtfz);
    // print that, too
    System.out.println("ZonedDateTime: "
                    + zdt2.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
    // convert to an Instant
    Instant instant = zdt.toInstant();
    // print the epoch millis
    System.out.println(instant.toEpochMilli());
}

Output:

ZonedDateTime: 2022-09-30T00:00:00Z[Atlantic/Reykjavik]
ZonedDateTime: 2022-09-30T00:00:00Z[Atlantic/Reykjavik]
1664496000000

If you want the LocalDate.atStartOfDay(), you could simply extract it by calling toLocalDate() on an instance of ZonedDateTime (in case that ZonedDateTime contains any time of day different from zero hours, minutes, seconds and further down the units).

Sign up to request clarification or add additional context in comments.

Comments

2

Corresponding to 2022-09-29T18:30:00.000Z, the IST in Fri Sep 30 00:00:00 IST 2022 refers to Indian Standard Time which has a time offset of UTC+05:30. You can build a formatter using .appendZoneText(TextStyle.SHORT, Set.of(ZoneId.of("Asia/Kolkata"))) with DateTimeFormatterBuilder as shown in the demo below:

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .appendPattern("EEE MMM dd HH:mm:ss")
                .appendLiteral(' ')
                .appendZoneText(TextStyle.SHORT, Set.of(ZoneId.of("Asia/Kolkata")))
                .appendLiteral(' ')
                .appendPattern("uuuu")
                .toFormatter(Locale.ENGLISH);

        Instant instant = ZonedDateTime.parse("Fri Sep 30 00:00:00 IST 2022", formatter).toInstant();
        System.out.println(instant);
    }
}

Output:

2022-09-29T18:30:00Z

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

Comments

0

Works for me

        DateTimeFormatter DATE_FORMAT_RULE = DateTimeFormatter.ofPattern("E MMM dd hh:mm:ss z yyyy", Locale.US);
        String date = "Fri Sep 30 00:00:00 IST 2022";
        Instant instant2 = LocalDate.parse(date, DATE_FORMAT_RULE)
                .atStartOfDay()
                .toInstant(ZoneOffset.UTC);

1 Comment

This gives you the wrong result. Depending on the interpretation of IST the string Fri Sep 30 00:00:00 IST 2022 corresponds to 2022-09-29T18:30:00Z or 2022-09-29T23:00:00Z. Your code gives neither of those, but instead 2022-09-30T00:00:00Z. You should get the time of day and the time zone abbreviation from the string too, which LocalDate.parse() does not do. A LocalDate is a date without time of day and without time zone.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.