tl;dr

OffsetDateTime
.parse( 
    "Wed, 20 Feb 2019 07:14:06 +0100" , 
    DateTimeFormatter.RFC_1123_DATE_TIME 
)
.toString()

2019-02-20T07:14:06+01:00

Details

Your problem has nothing to do with Java 8 versus Java 17.

Tip: Before blaming software that is formally specified, is thoroughly tested by enormous test suites, and is used by millions of programmers daily, suspect your own code first.

Locale

Specify a Locale. The locale determines the human language and cultural norms used in translating month names, etc.

If you do not specify a Locale, the JVM’s current default is applied implicitly. I would bet that when you ran your app at different times or on different machines, the JVM’s current default Locale varied.

Locale locale = Locale.US ;
DateTimeFormatter formatter = 
    DateTimeFormatter
    .ofPattern( "EEE, d MMM yyyy HH:mm:ss Z" )
    .withLocale( locale );
    
String input = "Wed, 20 Feb 2019 07:14:06 +0100" ;
ZonedDateTime zdt = ZonedDateTime.parse( input , formatter ) ;
String output = zdt.toString() ;
System.out.println( output );

See this code run at Ideone.com.

2019-02-20T07:14:06+01:00

RFC 1123

As commented by Ole V.V., your format happens to comply with the legacy standards RFC 1123, RFC 822, and RFC 2822.

The DateTimeFormatter class carries a pre-defined formatter object for that format. See the constant DateTimeFormatter.RFC_1123_DATE_TIME.

That pre-defined formatter already has the appropriate English-based locale required by the RFCs’ specifications. So no need to specify a Locale object here.

String input = "Wed, 20 Feb 2019 07:14:06 +0100" ;
DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME ;
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;

See this code run at Ideone.com.

2019-02-20T07:14:06+01:00

ISO 8601

Modern protocols use ISO 8601 rather than this outdated format. The java.time classes use ISO 8601 formats by default when parsing text or formatting a date-time instance.

I suggest you educate the publisher of your data about the virtues in using only ISO 8601 standard formats for communicating date-time values textually.

Answer from Basil Bourque on Stack Overflow
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › time › format › DateTimeFormatter.html
DateTimeFormatter (Java SE 17 & JDK 17)
January 20, 2026 - As this formatter has an optional element, it may be necessary to parse using parseBest(java.lang.CharSequence, java.time.temporal.TemporalQuery<?>...). The returned formatter has a chronology of ISO set to ensure dates in other calendar systems are correctly converted. It has no override zone and uses the STRICT resolver style. public static final DateTimeFormatter RFC_1123_DATE_TIME
🌐
Baeldung
baeldung.com › home › java › java dates › guide to datetimeformatter
Guide to DateTimeFormatter | Baeldung
March 26, 2025 - We can use DateTimeFormatter to uniformly format dates and times in an app with predefined or user-defined patterns. A quick and practical guide on transitioning to Java 8's new DateTime API.
Top answer
1 of 1
4

tl;dr

OffsetDateTime
.parse( 
    "Wed, 20 Feb 2019 07:14:06 +0100" , 
    DateTimeFormatter.RFC_1123_DATE_TIME 
)
.toString()

2019-02-20T07:14:06+01:00

Details

Your problem has nothing to do with Java 8 versus Java 17.

Tip: Before blaming software that is formally specified, is thoroughly tested by enormous test suites, and is used by millions of programmers daily, suspect your own code first.

Locale

Specify a Locale. The locale determines the human language and cultural norms used in translating month names, etc.

If you do not specify a Locale, the JVM’s current default is applied implicitly. I would bet that when you ran your app at different times or on different machines, the JVM’s current default Locale varied.

Locale locale = Locale.US ;
DateTimeFormatter formatter = 
    DateTimeFormatter
    .ofPattern( "EEE, d MMM yyyy HH:mm:ss Z" )
    .withLocale( locale );
    
String input = "Wed, 20 Feb 2019 07:14:06 +0100" ;
ZonedDateTime zdt = ZonedDateTime.parse( input , formatter ) ;
String output = zdt.toString() ;
System.out.println( output );

See this code run at Ideone.com.

2019-02-20T07:14:06+01:00

RFC 1123

As commented by Ole V.V., your format happens to comply with the legacy standards RFC 1123, RFC 822, and RFC 2822.

The DateTimeFormatter class carries a pre-defined formatter object for that format. See the constant DateTimeFormatter.RFC_1123_DATE_TIME.

That pre-defined formatter already has the appropriate English-based locale required by the RFCs’ specifications. So no need to specify a Locale object here.

String input = "Wed, 20 Feb 2019 07:14:06 +0100" ;
DateTimeFormatter f = DateTimeFormatter.RFC_1123_DATE_TIME ;
OffsetDateTime odt = OffsetDateTime.parse( input , f ) ;

See this code run at Ideone.com.

2019-02-20T07:14:06+01:00

ISO 8601

Modern protocols use ISO 8601 rather than this outdated format. The java.time classes use ISO 8601 formats by default when parsing text or formatting a date-time instance.

I suggest you educate the publisher of your data about the virtues in using only ISO 8601 standard formats for communicating date-time values textually.

🌐
Medium
medium.com › @mobile.prabeensoti › guide-to-data-time-formatter-in-java17-65d498f5d494
Guide To Data Time Formatter in Java17 | by Prabeen Soti | Medium
January 31, 2024 - LocalDate anotherSummerDay = LocalDate.of(2024, 1, 30); LocalTime anotherTime = LocalTime.of(13, 12, 45); ZonedDateTime zonedDateTime = ZonedDateTime.of(anotherSummerDay, anotherTime, ZoneId.of("America/New_York")); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT) .format(zonedDateTime));
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › time › format › DateTimeFormatter.html
DateTimeFormatter (Java Platform SE 8 )
October 20, 2025 - Java™ Platform Standard Ed. 8 ... Formatter for printing and parsing date-time objects. This class provides the main application entry point for printing and parsing and provides common implementations of DateTimeFormatter:
🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.desktop › javax › swing › text › DateFormatter.html
DateFormatter (Java SE 17 & JDK 17)
January 20, 2026 - DateFormatter is an InternationalFormatter that does its formatting by way of an instance of java.text.DateFormat.
Find elsewhere
Top answer
1 of 3
1

I'm having the same problem. I found this: https://bugs.openjdk.org/browse/JDK-8297504

Basically it says in older unicode CLDR (v33) which java 11 is based on, German terms for AM/PM is nachm. and vorm.

But in CLDR v44 which java17 is based on they changed it to AM/PM.

This is the quote from the ticket(https://bugs.openjdk.org/browse/JDK-8297504):

It turned out that the change came from the upstream CLDR. In CLDR v33 which JDK 11 is based on, "pm" string is localized into German "nachm." (look for "·de·" in the right column): https://www.unicode.org/cldr/cldr-aux/charts/33/by_type/date_&_time.gregorian.html#72c7f54616968b69

whereas in CLDR v42 which the latest JDK is based on, "pm" string in German is "PM": https://unicode-org.github.io/cldr-staging/charts/latest/by_type/date_&_time.gregorian.html#72c7f54616968b69

So the current right way in German based on recent unicode is AM/PM

2 of 3
0

Creating proper datetime format with correct Chronology and Locale will give am/pm in desired locale. For Germany and Chinese, I was able to get correct data, but for Hindi and Italy it’s not giving expected output. May be this is how data is showed in their respective region.

final String pattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(FormatStyle.FULL, FormatStyle.FULL, Chronology.ofLocale(Locale.GERMAN),Locale.GERMAN);
final DateTimeFormatter targetFormat = DateTimeFormatter.ofPattern(pattern).withLocale(Locale.GERMAN);
final String value = ZonedDateTime.now().format(targetFormat);
🌐
GitHub
github.com › AdoptOpenJDK › openjdk-jdk11 › blob › master › src › java.base › share › classes › java › time › format › DateTimeFormatter.java
openjdk-jdk11/src/java.base/share/classes/java/time/format/DateTimeFormatter.java at master · AdoptOpenJDK/openjdk-jdk11
import java.time.format.DateTimeFormatterBuilder.CompositePrinterParser; import java.time.temporal.ChronoField; import java.time.temporal.IsoFields; import java.time.temporal.TemporalAccessor; import java.time.temporal.TemporalField; import java.time.temporal.TemporalQuery; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Set; import sun.util.locale.provider.TimeZoneNameUtility; ·
Author   AdoptOpenJDK
🌐
Android Developers
developer.android.com › api reference › datetimeformatter
DateTimeFormatter | API reference | Android Developers
Skip to main content · English · Deutsch · Español – América Latina · Français · Indonesia · Polski · Português – Brasil · Tiếng Việt · 中文 – 简体
🌐
Reddit
reddit.com › r/javahelp › issue with time parsing in java 17's parsebest method.
r/javahelp on Reddit: Issue with time parsing in Java 17's parsebest method.
December 23, 2022 -

Hi All, i am using DateTimeformatter's parsebest method to parse dateTime, it was working fine in the Java 11 but once after changing it to java 17 it throws error.

DateTimepattern: yyyy-MM-dd hh:mm:ss a

lets say format is the DateTime Object.

So now, i put the code like this,

fmt.parseBest(str, ZonedDateTime::from, LocalDateTime::from, LocalDate::from, LocalTime::from);

where str: 2020-12-01 03:01:01 PM

In java 17 it throws error like java.time.format.DateTimeParseException: Text '2020-12-01 03:01:01 PM' could not be parsed at index 20.

java.time.format.DateTimeParseException: Text '2020-12-01 03:01:01 PM' could not be parsed at index 20
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052)
at java.base/java.time.format.DateTimeFormatter.parseBest(DateTimeFormatter.java:2000)

I read through oracle jdk documentation to find info regarding but no luck :( . Can anyone please let me know what's wrong here, or how do I change this behavior. Thank you for your time reading this.

Top answer
1 of 3
1
On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge. If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options: Limiting your involvement with Reddit, or Temporarily refraining from using Reddit Cancelling your subscription of Reddit Premium as a way to voice your protest. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
2 of 3
1
Please ensure that: Your code is properly formatted as code block - see the sidebar (About on mobile) for instructions You include any and all error messages in full You ask clear questions You demonstrate effort in solving your question/problem - plain posting your assignments is forbidden (and such posts will be removed) as is asking for or giving solutions. Trying to solve problems on your own is a very important skill. Also, see Learn to help yourself in the sidebar If any of the above points is not met, your post can and will be removed without further warning. Code is to be formatted as code block (old reddit: empty line before the code, each code line indented by 4 spaces, new reddit: https://i.imgur.com/EJ7tqek.png ) or linked via an external code hoster, like pastebin.com, github gist, github, bitbucket, gitlab, etc. Please, do not use triple backticks (```) as they will only render properly on new reddit, not on old reddit. Code blocks look like this: public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } } You do not need to repost unless your post has been removed by a moderator. Just use the edit function of reddit to make sure your post complies with the above. If your post has remained in violation of these rules for a prolonged period of time (at least an hour), a moderator may remove it at their discretion. In this case, they will comment with an explanation on why it has been removed, and you will be required to resubmit the entire post following the proper procedures. To potential helpers Please, do not help if any of the above points are not met, rather report the post. We are trying to improve the quality of posts here. In helping people who can't be bothered to comply with the above points, you are doing the community a disservice. I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
🌐
ZetCode
zetcode.com › java › datetimeformatter
Java DateTimeFormatter - formatting and parsing datetime values in Java
In this article we show how to formate and parse datetime values in Java with DateTimeFormatter.
Top answer
1 of 2
3

You’ve not given enough info to answer directly. But here are some pointers.

java.util.Date#toString tells a lie

The toString method of Date tells a lie. While generating text to report the UTC value of the moment within the object, that method applies the JVM’s current default time zone. This creates the illusion of a time zone where actually the value has an offset of zero hours-minutes-seconds from the temporal meridian of UTC.

That class has a terrible name. It does not represent a date. It represents a moment, a point on the timeline, a date with time of day as seen from an offset of zero.

Solution: Stop using that class.

public class SampleClass 
{
    Integer id ;
    java.time.LocalDate received ; 
    …
}

Avoid legacy date-time classes

You are using terribly flawed date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.

java.time.LocalDate

when we send say "25-01-2017"

Parse as a java.time.LocalDate.

Define a custom formatting pattern to match your input.

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MM-uuuu" ) ;

Parse.

LocalDate date = LocalDate.parse( "25-01-2017" , f ) ;

No time of day is involved. Your problem is eliminated.

2 of 2
0

The format is always the same. When you concatenate a Date to a String the method Date.toString() is used to convert the date:

Converts this Date object to a String of the form:

dow mon dd hh:mm:ss zzz yyyy

The difference is probably because the first date is not containing time information. Why is that we don't know because there are no details in the question of how sampleClass has been constructed or if there is a difference in the versions of other libraries.

🌐
Oracle
docs.oracle.com › en › java › javase › 17 › docs › api › java.base › java › time › format › package-summary.html
java.time.format (Java SE 17 & JDK 17)
July 15, 2025 - Instances are generally obtained from DateTimeFormatter, however DateTimeFormatterBuilder can be used if more power is needed. Localization occurs by calling withLocale(Locale) on the formatter. Further customization is possible using DecimalStyle. Unless otherwise noted, passing a null argument to a constructor or method in any class or interface in this package will cause a NullPointerException to be thrown. The Javadoc "@param" definition is used to summarise the null-behavior.