2

I want to convert to this string to LocalDateTime object. How can I do that?

"Thu Aug 29 17:46:11 GMT+05:30 2019"

I already try something, but it didn't work.

    final String time = "Thu Aug 29 17:46:11 GMT+05:30 2019";
    final String format = "ddd MMM DD HH:mm:ss 'GMT'Z YYYY";

    DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(format);
    LocalDateTime localDateTime = LocalDateTime.parse(time, dateTimeFormatter);

Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "Thu Aug 29 17:46:11" at org.joda.time.format.DateTimeFormatter.parseLocalDateTime(DateTimeFormatter.java:900) at org.joda.time.LocalDateTime.parse(LocalDateTime.java:168)

Robur_131
  • 374
  • 5
  • 15
Nimantha
  • 165
  • 3
  • 11
  • 2
    What makes you think `ddd` would match to `Thu`? Did you consider reading the [docs](https://www.joda.org/joda-time/apidocs/org/joda/time/format/DateTimeFormat.html)? – shmosel Aug 30 '19 at 00:37
  • Oh... i read wrong documentation i think.... Thanks for ur help. I got the solution. – Nimantha Aug 30 '19 at 00:55
  • Why a `LocalDateTime` object? For most purposes it would be better to keep the GMT offset from the string (which a `LocalDateTime` doesn’t do; consider `DateTime`). – Ole V.V. Aug 30 '19 at 07:53

3 Answers3

4

tl;dr

FYI, the Joda-Time project is now in maintenance mode, advising migration to the java.time classes. See Tutorial by Oracle.

OffsetDateTime.parse( 
    "Thu Aug 29 17:46:11 GMT+05:30 2019" , 
    DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss OOOO uuuu").withLocale( Locale.US ) 
)
.toString()

2019-08-29T17:46:11+05:30

LocalDateTime cannot represent a moment

"Thu Aug 29 17:46:11 GMT+05:30 2019"

I want to convert to this string to LocalDateTime object.

You cannot.

  • The input represents a moment, a specific point on the timeline.
  • A LocalDateTime cannot represent a moment. A LocalDateTime has only a date and a time-of-day but lacks the context of a time zone or offset-from-UTC.

Trying to handle your input as a LocalDateTime would mean discarding valuable information. That would be like handling a amount of money as simply a BigDecimal while throwing away information about which currency.

OffsetDateTime

You input string includes an offset-from-UTC of five and a half hours ahead. So parse as an OffsetDateTime object.

Define a custom formatting pattern to match your input, using the DateTimeFormatter class.

Define

String input = "Thu Aug 29 17:46:11 GMT+05:30 2019" ;
DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss OOOO uuuu").withLocale( Locale.US );
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;

odt.toString(): 2019-08-29T17:46:11+05:30

Tip: That input format is terrible. Educate the publisher of those input string about the standard ISO 8601 for practical date-time formats.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
3

Note that Joda-Time is considered to be a largely “finished” project. No major enhancements are planned. If using Java SE 8, please migrate to java.time (JSR-310).

This is quoted from the Joda-Time home page. I should say that it endorses the answer by Basil Bourque. In any case if you insist on sticking to Joda-Time for now, the answer is:

    final String time = "Thu Aug 29 17:46:11 GMT+05:30 2019";
    final String format = "EEE MMM dd HH:mm:ss 'GMT'ZZ YYYY";

    DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern(format)
            .withLocale(Locale.ENGLISH)
            .withOffsetParsed();
    DateTime dateTime = DateTime.parse(time, dateTimeFormatter);
    System.out.println(dateTime);

Output:

2019-08-29T17:46:11.000+05:30

  • In the format pattern string
    • You need EEE for day of week. d is for day of month.
    • You need lowercase dd for day of month; uppercase DD is for day of year
    • I have put in ZZ because according to the docs this is for offset with a colon; Z works in practice too
  • Since Thu and Aug are in English, you need an English speaking locale. Since I believe your string comes from Date.toString() originally, which always produces English, I found Locale.ROOT appropriate.
  • I found it better to parse into a DateTIme. To preserve the offset from the string we need to specify that through withOffsetParsed() (you can always convert to LocalDateTime later if desired).

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

The format string you provided for parsing doesn't looks right with the text format you've actually got. You need to parse first, then format. Just test below code,

    SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy",Locale.getDefault());
    Date dt = null;
    try {
        dt = format.parse("Thu Aug 29 17:46:11 GMT+05:30 2019");
        SimpleDateFormat out = new SimpleDateFormat("MMM dd, yyyy h:mm a");
        String output = out.format(dt);
        Log.e("OUTPUT",output);
    } catch (Exception e) {
        e.printStackTrace();
    }
Krishna Vyas
  • 1,009
  • 8
  • 25
  • Why would you want to use the super old cumbersome legacy date API of java instead the modern date-time API? OP is also using jodatime already. – Zabuzard Aug 30 '19 at 11:18
  • Because someone wants use old code with some modification instead of using large library. – Krishna Vyas Aug 30 '19 at 12:04
  • The modern date-time library is part of Java since 8. It is not external. Your solution works and is good for Q&A but I would clearly mark it as legacy solution. Anyone having Java 8 or newer should use the modern API. There is no valid reason to not use it, except if you do not have Java 8. – Zabuzard Aug 30 '19 at 12:59
  • Sorry, I'm talking about an Android – Krishna Vyas Aug 30 '19 at 13:48