20250207 ‐ Java - cywongg/2025 GitHub Wiki

Short answer:

  1. There isn’t a fundamental change between Java 8 and Java 11 in how SimpleDateFormat handles parsing of date-time strings. If you provide a pattern with seconds, but the actual string lacks seconds (or vice versa), it may fail in both Java 8 and Java 11 unless your pattern matches your actual string.
  2. If you have a LocalDateTime at the start of day (00:00) and want to format it as a string with the pattern "yyyyMMdd:HH:mm:ss" (for example, 20250101:00:00:00), you should use the java.time.format.DateTimeFormatter in your Java code (recommended over SimpleDateFormat for any modern Java application).

1. Potential Parsing Issue with SimpleDateFormat

If you use SimpleDateFormat to parse, for instance, "20250101:00:00" (without seconds) but your pattern is "yyyyMMdd:HH:mm:ss" (with seconds), SimpleDateFormat will throw a ParseException in both Java 8 and Java 11 because the incoming string doesn’t match the pattern exactly.

Example using SimpleDateFormat:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SimpleDateFormatExample {
    public static void main(String[] args) {
        // Pattern includes seconds
        SimpleDateFormat sdfWithSeconds = new SimpleDateFormat("yyyyMMdd:HH:mm:ss");

        // This string is missing the seconds part
        String input = "20250101:00:00";

        try {
            // This will throw ParseException because the pattern expects seconds but they're not present
            Date parsedDate = sdfWithSeconds.parse(input);
            System.out.println("Parsed date = " + parsedDate);
        } catch (ParseException e) {
            System.err.println("Failed to parse: " + e.getMessage());
        }
    }
}

How to avoid the parsing error:

  • Make sure the string includes seconds if your pattern includes seconds.
  • Or adjust your pattern to skip seconds, e.g. "yyyyMMdd:HH:mm" if you truly don’t have seconds in the input.

Java 8 → Java 11 didn’t introduce any default parsing changes in SimpleDateFormat that would cause one to fail and not the other. Both versions should behave the same when patterns and actual strings don’t match.


2. Recommended Way: Using java.time (DateTimeFormatter)

Starting with Java 8, you have the newer date/time API (java.time package). You typically use DateTimeFormatter instead of SimpleDateFormat. This is often more robust and recommended because:

  • The modern API is thread-safe (unlike SimpleDateFormat).
  • It handles date/time objects like LocalDateTime more naturally.

2.1 Parsing a String to LocalDateTime

Suppose you have a string "20250101:00:00:00" and you want a LocalDateTime:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateTimeFormatterParseExample {
    public static void main(String[] args) {
        String dateString = "20250101:00:00:00";

        // Pattern matches entire string
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd:HH:mm:ss");
        
        LocalDateTime localDateTime = LocalDateTime.parse(dateString, formatter);
        System.out.println("Parsed LocalDateTime: " + localDateTime);
    }
}

2.2 Formatting a LocalDateTime

If you have a LocalDateTime at the start of the day (00:00), and you’d like to format it as "yyyyMMdd:HH:mm:ss", do:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateTimeFormatterFormatExample {
    public static void main(String[] args) {
        // Start-of-day example
        LocalDateTime startOfDay = LocalDateTime.of(2025, 1, 1, 0, 0, 0);

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd:HH:mm:ss");
        String formatted = startOfDay.format(formatter);

        System.out.println("Formatted date-time: " + formatted);
        // Output: 20250101:00:00:00
    }
}

Summary

  • There is no specific change from Java 8 to Java 11 that alters how SimpleDateFormat parses or formats strings regarding seconds. If your pattern and input string do not match perfectly, you’ll get a ParseException in both versions.

  • It’s generally recommended to use the java.time API with DateTimeFormatter in Java 8 and onwards. To format a start-of-day LocalDateTime with a pattern like "yyyyMMdd:HH:mm:ss", use:

    String output = localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd:HH:mm:ss"));
    

Yes, you can use a SimpleDateFormat as long as you first convert your LocalDateTime (from the java.time API) into an old-school Date (from the java.util API). SimpleDateFormat works with java.util.Date, not directly with LocalDateTime.

However, be careful with time zones when converting. For example, if you want to interpret your LocalDateTime in your system’s default time zone and get a Date, you can do this:

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

public class SimpleDateFormatWithLocalDateTime {
    public static void main(String[] args) {
        // Example LocalDateTime:
        LocalDateTime localDateTime = LocalDateTime.of(2025, 1, 1, 0, 0, 0);

        // Convert LocalDateTime -> ZonedDateTime -> Date
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        Date oldStyleDate = Date.from(zonedDateTime.toInstant());

        // Now use SimpleDateFormat to format it:
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd:HH:mm:ss");
        String formatted = sdf.format(oldStyleDate);

        System.out.println(formatted);  // e.g., 20250101:00:00:00
    }
}

This approach allows you to:

  1. Create a ZonedDateTime from your LocalDateTime, specifying the time zone you want.
  2. Convert the ZonedDateTime to a Date.
  3. Use SimpleDateFormat on the resulting Date.

Note that any time zone or daylight-saving offset differences will be applied in the .atZone(...) step. Always confirm you’re using the correct ZoneId.


Why Prefer DateTimeFormatter Over SimpleDateFormat

While you can use SimpleDateFormat, it’s generally recommended to stay in the java.time world and use DateTimeFormatter:

// Directly format a LocalDateTime:
String output = localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMdd:HH:mm:ss"));

• It’s thread-safe (unlike SimpleDateFormat).
• No need for conversion to Date and potential time-zone pitfalls.

But if your legacy code requires a Date or you need SimpleDateFormat, the above conversion snippet shows you how to do it properly.

Short Answer

  • SimpleDateFormat is part of the older java.util date-time API and can only parse/format Date objects, not the modern LocalDateTime.
  • The fact that SimpleDateFormat doesn’t work directly with LocalDateTime is not because of an upgrade from Java 8 to Java 11. It’s simply due to the difference between the old date-time API (pre–Java 8) and the newer java.time API (added in Java 8).

Why SimpleDateFormat Doesn’t Parse LocalDateTime Directly

  1. LocalDateTime is part of the newer Java 8+ Date-Time API, introduced with the java.time package (JSR 310).
  2. SimpleDateFormat was introduced prior to Java 8, in the java.text package, and it works with the old java.util.Date / java.util.Calendar classes.

Hence, SimpleDateFormat cannot accept a LocalDateTime object and parse or format it directly. It only deals with “old” Date objects.


Is This Behavior Due to Java 8 → Java 11 Changes?

No. Java 8 introduced the new date-time API. Java 11 did not change the fact that SimpleDateFormat only works with Date. This limitation has existed well before Java 8 and continues unchanged in Java 11 (and beyond).


How to Work Around This

If you must use SimpleDateFormat (e.g., for some legacy code), you can:

  1. Convert the LocalDateTime to a Date by applying a time zone via ZonedDateTime:

    LocalDateTime localDateTime = LocalDateTime.of(2025, 1, 1, 0, 0, 0);
    ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
    Date oldStyleDate = Date.from(zonedDateTime.toInstant());
    
  2. Use SimpleDateFormat on the Date:

    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd:HH:mm:ss");
    String result = sdf.format(oldStyleDate);
    System.out.println(result);
    

Recommended Modern Approach

It’s strongly recommended to use the modern java.time.format.DateTimeFormatter instead of SimpleDateFormat. This way, you can parse/format LocalDateTime objects directly without converting back and forth to Date:

LocalDateTime localDateTime = LocalDateTime.of(2025, 1, 1, 0, 0, 0);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd:HH:mm:ss");
String output = localDateTime.format(formatter);
System.out.println(output);  // e.g., "20250101:00:00:00"

Summary

  • SimpleDateFormat and LocalDateTime are from two different APIs.
  • This mismatch is not the result of any Java version upgrade.
  • If you must use SimpleDateFormat, convert LocalDateTimeDate. Otherwise, prefer the java.time API and its DateTimeFormatter.