Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Find out a work around to bypass Java.time bug

I found a java.time bug recently. it is very easy to reproduce it;

I tested it on JDK 17.0.10 and JDK 21.0.4 on MacOS X and Centos Stream 9

Code as:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

public class JakartaDateTime {

public static void main(String[] args) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy");
    LocalDateTime now = LocalDateTime.now();
    System.out.println(formatter.format(now));
}

This code will print a string

Fri Sept 06 23:10:23 2024

Sure,it is not I expected, the expected result should be:

Fri Sep 06 23:10:23 2024

I had report it as a bug to java bug report and Oracle bug database ID: 9077542. Im sure it will not be fixed soon. So I have to find out a work around to avoid it.

I’m trying to use gson to map a income json to our java class, json object key/value pair as:

{"date":"Fri Sep 06 23:10:23 2024"}

so, I have to code a deserialiser to pars that string to java.time.LocalDateTime. I did some thing like this:

public class EuDateTimeDeserializer implements JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
    String dateTimeStr =jsonElement.getAsString();
    if(!ThssUtils.isValidString(dateTimeStr)){
        return null;
    }else {
        return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss yyyy"));
    }
  }
}

But this deserialiser only works on other months than September.

throws error as:

java.time.format.DateTimeParseException: Text 'Fri Sep  6 15:42:12 2024' could not be parsed at index 4

That means, the deserialiser not recognise above string.

Does any one have this experience to find out a work around to avoid previous java.time bug?

Please advise!

>Solution :

tl;dr

Not a bug. Specify Locale.

DateTimeFormatter.ofPattern( … ).withLocale( locale )

Feature, not a bug

While you neglected to mention exactly what you consider to be a "bug", I presume you mean the missing t in Sept vs Sep.

Localization

The spelling, abbreviation, and punctuation in date-time formatting depends on a Locale. The human language and cultural norms contained in a Locale object control the process of [localization][1].

Specify a Locale

Here we specify English in United States. We get Sep.

LocalDateTime ldt = LocalDateTime.of( 2024 , Month.SEPTEMBER , 6 , 23 , 10 , 23 , 0 );
System.out.println( "ldt = " + ldt );

Locale locale = Locale.of( "en" , "US" );
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "EEE MMM dd HH:mm:ss yyyy" ).withLocale( locale );
String output = formatter.format( ldt );

System.out.println( "output = " + output );

ldt = 2024-09-06T23:10:23

output = Fri Sep 06 23:10:23 2024

Change that locale to English in Australia. We get Sept.

Locale locale = Locale.of( "en" , "AU" );

ldt = 2024-09-06T23:10:23

output = Fri Sept 06 23:10:23 2024

Please retract your faulty bug report.

Tip: Always suspect your own code, or your own misunderstanding, before doubting a library bundled with Java. Yes, a bug could creep into the the codebase of an implementation of Java. But bugs like your allegation here is rare. The [OpenJDK][2] code base used for most implementations of Java is some of the most thoroughly examined and tested code ever produced outside of specialties such as military & aerospace.

Avoid LocalDateTime.now

By the way, your code calls LocalDateTime.now. I cannot imagine a scenario where that is the smart thing to do.

A LocalDateTime object represens a date with a time-of-day but lacks the context of an offset-from-UTC or a time zone. Without that context, we have no way to know if you meant 11 PM in Toowoomba Australia, 11 PM in Toulouse France, 11 PM in Toledo Ohio US — three very different moments, several hours apart.

To capture the current moment, use one of the three classes that track a specific point on the timeline:

  • Instant
  • OffsetDateTime
  • ZonedDateTime

The first and third are most common for business purposes, while the second is used mainly for exchange with a SQL database.

Instant now = Instant.now() ;  // Capture current moment as seen "in UTC", meaning an offset from UTC of zero hours-minutes-seconds. 

See that same moment through the wall-clock/calendar of a particular time zone.

ZoneId z = ZoneId.of( "Australia/Brisbane" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;


  [1]: https://en.wikipedia.org/wiki/Internationalization_and_localization
  [2]: https://en.wikipedia.org/wiki/OpenJDK
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading