Home > Software design >  How can I parse and format this string date 2022-11-08 10:28:04.282551-06?
How can I parse and format this string date 2022-11-08 10:28:04.282551-06?

Time:11-11

I have this code:

public static void main(String[] args) throws ParseException {
        String fecha = "2022-11-08 10:28:04.282551-06";
        
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        Date e = simpleDateFormat.parse(fecha);
        SimpleDateFormat newSimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        System.out.println(newSimpleDateFormat.format(e));
        
    }

And this error:

Exception in thread "main" java.text.ParseException: Unparseable date: "2022-11-08 10:28:04.282551-06"
    at java.text.DateFormat.parse(DateFormat.java:366)
    at Ejemplos.main(Ejemplos.java:11)

I want my new date like this: 2022-11-08 10:28:04.282551 This values after dot *282551 *sometimes can be less, for example: *282 *or 2825 and sometimes there is not a dot, for example: 2022-11-08 10:28:04-06

CodePudding user response:

It is strongly recommended to stop using the outdated Date, Calendar, SimpleDateFormat, ... classes - these were replaced by classes from the java.time package and sub-packages like LocalDateTime, ZonedDateTime, DateTimeFormatter, ...

Since we have a fractional part with variable size, we need the DateTimeFormatterBuilder to create the corresponding formatter for parsing the string:

private static final DateTimeFormatter PARSE_FORMATTER = 
    new DateTimeFormatterBuilder()
    .appendPattern("uuuu-MM-dd HH:mm:ss")  // date time
    .optionalStart()
    .appendFraction(ChronoField.MICRO_OF_SECOND, 3, 6, true)  // optional fractions
    .optionalEnd()
    .appendPattern("x")  // time zone offset
    .toFormatter()
    .withLocale(Locale.ROOT);  // replace as needed


public static ZonedDateTime convert(String str) {
    return ZonedDateTime.parse(str, PARSE_FORMATTER);
}

To have a string like "2022-11-08 10:28:04.282551" format, we need an additional formatter:

private static final DateTimeFormatter FORMAT_FORMATTER = 
    DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");  // time zone is IGNORED!!

public static String convertToString(ZonedDateTime dateTime) {
    return dateTime.format(FORMAT_FORMATTER);
}

The previous both methods can (obviously) be merged together in one method, but it is preferable to work with date-time objects (ZonedDateTime, OffsetDateTime, LocalDateTime, ...) instead of strings - strings should only be used for output!

The above Formatter is not including the time zone information in the result, that can be very confusing (IMHO) - see last date of test output below. Please be sure that such is really required!!!
Otherwise we must change the zone of the ZonedDateTime like in dateTime.withZoneSameInstant(ZoneId.systemDefault()).format(FORMAT_FORMATTER);
or include the time zone information in the output formatter.


Test for above methods:

public static void main(String[] args) {
    // just for testing
    Locale.setDefault(Category.DISPLAY, Locale.GERMANY);
    Locale.setDefault(Category.FORMAT, Locale.GERMANY);
    TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
    
    var data = """
        2022-11-08 10:28:04.282551-06
        2022-11-08 10:28:04.282-06
        2022-11-08 10:28:04-06
        2022-11-08 10:28:04 02
        """.split("\n");
    for (var str : data) {
        test(str);
    }
}

private static void test(String str) {
    try {
        System.out.printf("%-30s  ->  %s%n", str, convertToString(convert(str)));
    } catch (Exception ex) {
        System.err.printf("%-30s  ->   %s%n", str, ex);
    }
}

Output:

openjdk version "19" 2022-09-20
OpenJDK Runtime Environment (build 19 36-2238)
OpenJDK 64-Bit Server VM (build 19 36-2238, mixed mode, sharing)
2022-11-08 10:28:04.282551-06   ->  2022-11-08 10:28:04
2022-11-08 10:28:04.282-06      ->  2022-11-08 10:28:04
2022-11-08 10:28:04-06          ->  2022-11-08 10:28:04
2022-11-08 10:28:04 02          ->  2022-11-08 10:28:04

CodePudding user response:

I found the solution for your problem. first you need to split your string and after that you can format it. try this

public static void main(String[] args) throws ParseException {
    String fecha = "2022-11-08 10:28:04.282551-06";
    String[] parts = fecha.split("\\.");
    String part1 = parts[0];
    String part2 = parts[1];

    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    System.out.println(simpleDateFormat.parse(part1));

}
  • Related