2

I have many formats of inputs coming for DateTime column which includes 1."MM/dd/yyyy HH:mm:ss a" 2."MM/dd/yyyy HH:mm:ss" 3."MM/dd/yyyy HH:mm" 4."yyyyMMdd"

This should be formatted and giving me a output of the longest format which is 1."MM/dd/yyyy HH:mm:ss a" filling in the remaining format with either 00 values if doesn't exist.

This is what I am trying:

DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(""
                + "[MM/dd/yyyy HH:mm:ss a]"
                + "[MM/dd/yyyy HH:mm:ss]"
                + "[MM/dd/yyyy HH:mm]"
                + "[yyyyMMdd]");


return
me.setManufacturingDate(LocalDateTime.parse(mm.getManufacturingDate().toString(),
                    dateFormatter));

Please do recommend a different way of method if I am heading wrong or fix this problem for me. Thanks in advance and any help will be much appreciated.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110

1 Answers1

4
  1. You can use DateTimeFormatterBuilder#parseDefaulting and keep the optional patterns inside the square bracket.
  2. I also strongly suggest to use DateTimeFormatterBuilder#parseCaseInsensitive to deal with case (e.g. AM/am).
  3. Also, never forget to use Locale with a DateTimeFormatter because it is a Locale-sensitive type.
  4. Last but not the least, note that H is use for 24-hour format while h is used for 12-hour format.

Demo:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
                .parseCaseInsensitive()
                .appendPattern("[MM/dd/uuuu hh:mm:ss a][MM/dd/uuuu HH[:mm[:ss]]][uuuuMMdd[ hh:mm:ss a]")
                .parseDefaulting(ChronoField.CLOCK_HOUR_OF_AMPM, 0)
                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                .toFormatter(Locale.ENGLISH);

        // Test
        String[] arr = { "08/25/2021 10:20:30 am", "08/25/2021 10:20:30", "08/25/2021 10:20", "20210825" };

        for (String s : arr) {
            LocalDateTime ldt = LocalDateTime.parse(s, dateFormatter);
            System.out.println(ldt);
        }
    }
}

Output:

2021-08-25T10:20:30
2021-08-25T10:20:30
2021-08-25T10:20
2021-08-25T00:00

ONLINE DEMO

Note: You can use y instead of u but I prefer u to y.

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


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
  • Hi For me using the above solution is throwing the following error: ERROR: java.time.format.DateTimeParseException: Text '8' could not be parsed, unparsed text found at index 0 INPUT: 08/25/2021 10:20:30 am – Rakesh Kumar Aug 25 '21 at 20:11
  • @RakeshKumar - I have also linked an online editor where it is running without any problem. What is the version of JDK you are using? – Arvind Kumar Avinash Aug 25 '21 at 20:13
  • Hi Arvind, sorry I see that it's working fine in demo you shared but I am trying to figure out what could be my problem and BTW I am using 14.0.2 version – Rakesh Kumar Aug 25 '21 at 20:23
  • @RakeshKumar - [Here](https://www.tutorialspoint.com/compile_java_online.php) is another online editor where you can copy and paste my code as it is and execute. – Arvind Kumar Avinash Aug 25 '21 at 20:50