0

I am trying to convert an Instant to a String with the format like "10 Jul 2021, 10:00 PM".

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd LLL yyyy, hh:mm a");
String formattedDate = formatter.withZone(ZoneId.from(ZoneOffset.UTC)).format(instant);

It works as expected on my machine, but it comes out as "10 7 2021, 10:00 PM" in other environments.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Do you have any reason to use 'LLL' for month instead of 'MMM'? Probably, it can help you to solve your problem: https://stackoverflow.com/questions/30518954/datetimeformatter-month-pattern-letter-l-fails – Georgii Lvov May 18 '21 at 16:04
  • 1
    Related: (1) [How to format Simple Date Formatter in Java as dd-3 letter month-yyyy?](https://stackoverflow.com/q/57956746/10819573) (2) [Getting a Date with “ShortenedMonth/dd” format](https://stackoverflow.com/q/11312129/10819573) (3) [Cannot parse date string containing three letter month](https://stackoverflow.com/q/34964524/10819573) (4) [How to display First three letters of the month in android datepicker](https://stackoverflow.com/q/33229011/10819573) (5) [How do I abbreviate month to 3 characters?](https://stackoverflow.com/q/56025129/10819573) – Arvind Kumar Avinash May 19 '21 at 20:26

2 Answers2

3

Use MMM for month abbreviation and specify desired locale

    Instant instant = Instant.ofEpochSecond(1_625_954_400);
    DateTimeFormatter formatter
            = DateTimeFormatter.ofPattern("dd MMM uuuu, hh:mm a", Locale.US);
    String formattedDate = formatter.withZone(ZoneOffset.UTC).format(instant);
    System.out.println(formattedDate);

Output:

10 Jul 2021, 10:00 PM

This should be stable across computers except that it may theoretically vary with different Java versions. I don’t expect it to.

What went wrong in your code?

By all likelihood the inconsistent results that you have observed are due to different locales. When not instructed otherwise, the one-arg DateTimeFormatter.ofPattern() gives you a formatter that is using the default locale of the JVM (usually taking from an operating system setting). This will give you very varied results on computers and JVMs with different language and region settings. To confuse things further locale data vary with Java version and locale provider setting (the java.locale.providers system property). On my Java 8 very many locales gave 7 as month from LLL and only German have Jul. On my Java 11 only the Vai language of Liberia gives 7 while many give Jul.

Format pattern letter L is for the stand-alone form of month name or abbreviation and should generally not be used when the month is part of a date as it is in your case. In most locales L and M give the same results, but there are locales where there’s a difference and on purpose.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Try this code: this will work 100%

DateFormat df = new SimpleDateFormat("dd-MMMM-yyyy HH:mm a");
    Date date = new Date(System.currentTimeMillis());
    String infi = df.format(date);

And the output be like

18-May-2021 11:31 PM

  • That won't match the format specified in the question of "10 Jul 2021, 10:00 PM" though. – Jon Skeet May 18 '21 at 18:50
  • By all means avoid `SimpleDateFormat`, That one is a notorious troublemaker of a class. The OP was wisely asking about `DateTimeFormatter` from java.time, the modern and far superior date and time API. – Ole V.V. May 18 '21 at 19:09
  • From your code I got `18-maj-2021 14:37 PM`. I don’t think the OP wanted small `m` and `j`. I suggest you subtract from your *100%*. :-) – Ole V.V. May 18 '21 at 19:38