2

Now I have two different formats of date written in string:

String date1 = "2018-10-12 18:01:01";// yyyy-MM-dd HH:mm:ss
String date2 = "2018-10-12 18:01";//yyyy-MM-dd HH:mm

I am using joda and I want to convert the string to DateTime,the basic way is to use two formatter to parse each of them:

DateTimeFormatter formatter1 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter formatter2 = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm");
DateTime dt1 = formatter1.parseDateTime(date1);
DateTime dt2 = formatter2.parseDateTime(date2);

Above code blocks works fine but it created two formatter,since the date formate is very similar(the latter one just lack of seconds),I am wonder if there is a way that I can just use one formatter to parse all of them or I have to use two formatter?

Note: due to the production enviroment limit,I can not use java8 now,so I want to the answer based on joda

Thanks in advance!


I just tried as below,and got IllegalArgumentException: Invalid format

DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dt1 = formatter.parseDateTime(date1);
DateTime dt2 = formatter.parseDateTime(date2);
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
flyingfox
  • 13,414
  • 3
  • 24
  • 39
  • you can prob preprocess all `yyyy-MM-dd HH:mm` dates, i.e. append `:00` to them, if you can't find a solution – gherkin Oct 12 '18 at 22:12

3 Answers3

3

You can indicate that some parts of the format are optional using []

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm[:ss]");
LocalDateTime dateTime = LocalDateTime.parse("2018-10-12 18:01:01", formatter);
LocalDateTime dateTime1 = LocalDateTime.parse("2018-10-12 18:01", formatter);
System.out.println(dateTime + " " + dateTime1);

result is

2018-10-12T18:01:01 2018-10-12T18:01

Please see Patterns for Formatting and Parsing section for more info.

Anton Balaniuc
  • 10,889
  • 1
  • 35
  • 53
  • it's a bit annoying it's parsed as 01 though, should it not be 18:01:00 – gherkin Oct 12 '18 at 11:31
  • @gherkin it is actually `18:01:00`, if you do `dateTime1.getSecond()` returns `0`, probably it is just `DateTime.toString` issue, since it uses `yyyy-MM-dd HH:mm[:ss]` format – Anton Balaniuc Oct 12 '18 at 11:34
  • 1
    @gherkin, yep it is a formatter issue, if I use different formatter ` System.out.println(dateTime + " " + dateTime1.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));` it outputs as `18:01:00` – Anton Balaniuc Oct 12 '18 at 11:35
  • When I tested in my side,I got the error `Invalid format: "2018-10-10 10:10:12" is malformed at ":12"`,I am using `java8` and `joda2.4` test it – flyingfox Oct 12 '18 at 11:35
  • 1
    @lucumt, it is LocalDateTime from `java.time` package, the jdk class not an external one. I am afraid I don't know how to do it with `joda.time` – Anton Balaniuc Oct 12 '18 at 11:37
  • Because due to my environment limit I can not use `java8`,thus I have to use `joda` to do it – flyingfox Oct 12 '18 at 11:38
  • Oh, you can use the java.time API on Java 6 and 7 too, there’s a backport: [the ThreeTen Backport library](https://www.threeten.org/threetenbp/). – Ole V.V. Oct 13 '18 at 11:54
2

Two options:

  1. Use java.time, the modern Java date and time API through the ThreeTen Backport library.
  2. Use Joda-Time as you are already doing.

ThreeTen Backport

Two quotes from the Joda-Time home page:

Users are now asked to migrate to java.time (JSR-310).

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).

The good news is you can migrate even if using Java 6 or 7. The developers of java.time (lead by Stephen Colebourne, also the lead developer of Joda-Time) have also developed the ThreeTen Backport, the backport of java.time for Java 6 and 7. See the link at the bottom.

Anton Balaniuc is already showing the code in his good answer, so there’s no use for me to repeat that here.

Joda-Time

    String date1 = "2018-10-12 18:01:01";// yyyy-MM-dd HH:mm:ss
    String date2 = "2018-10-12 18:01";//yyyy-MM-dd HH:mm
    DateTimeFormatter parser = new DateTimeFormatterBuilder()
                    .appendPattern("yyyy-MM-dd HH:mm")
                    .appendOptional(DateTimeFormat.forPattern(":ss").getParser())
                    .toFormatter();
    DateTime dt1 = parser.parseDateTime(date1);
    DateTime dt2 = parser.parseDateTime(date2);
    System.out.println("dt1: " + dt1);
    System.out.println("dt2: " + dt2);

On my computer in Europe/Copenhagen time zone the output from this snippet was:

dt1: 2018-10-12T18:01:01.000+02:00
dt2: 2018-10-12T18:01:00.000+02:00

As you can see, the key to specifying optional parts in the format is the appendOptional method of DateTimeFormatterBuilder.

Links

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

You can use DateTimeFormatterBuilder class, something like this.

  private DateTimeFormatter formatterBuilder() {
        return new DateTimeFormatterBuilder()
                .appendPattern("yyyy-MM-dd HH:mm")
                .optionalStart().appendPattern(":ss").optionalEnd()
                .toFormatter();
    }
Mladen Savić
  • 472
  • 4
  • 10
  • 2
    Seems your solution is based on `java8`,I tested on `joda2.4` it do not have method called `optionalStart()` – flyingfox Oct 12 '18 at 11:25