20250207 ‐ Java - cywongg/2025 GitHub Wiki
Short answer:
- 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. - 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 thejava.time.format.DateTimeFormatter
in your Java code (recommended overSimpleDateFormat
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 aParseException
in both versions. -
It’s generally recommended to use the
java.time
API withDateTimeFormatter
in Java 8 and onwards. To format a start-of-dayLocalDateTime
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:
- Create a
ZonedDateTime
from yourLocalDateTime
, specifying the time zone you want. - Convert the
ZonedDateTime
to aDate
. - Use
SimpleDateFormat
on the resultingDate
.
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 olderjava.util
date-time API and can only parse/formatDate
objects, not the modernLocalDateTime
.- The fact that
SimpleDateFormat
doesn’t work directly withLocalDateTime
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 newerjava.time
API (added in Java 8).
SimpleDateFormat
Doesn’t Parse LocalDateTime
Directly
Why LocalDateTime
is part of the newer Java 8+ Date-Time API, introduced with thejava.time
package (JSR 310).SimpleDateFormat
was introduced prior to Java 8, in thejava.text
package, and it works with the oldjava.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:
-
Convert the
LocalDateTime
to aDate
by applying a time zone viaZonedDateTime
:LocalDateTime localDateTime = LocalDateTime.of(2025, 1, 1, 0, 0, 0); ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault()); Date oldStyleDate = Date.from(zonedDateTime.toInstant());
-
Use
SimpleDateFormat
on theDate
: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
andLocalDateTime
are from two different APIs.- This mismatch is not the result of any Java version upgrade.
- If you must use
SimpleDateFormat
, convertLocalDateTime
→Date
. Otherwise, prefer thejava.time
API and itsDateTimeFormatter
.