Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8329375

English date format MMM does not always yield 3 letter month

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Tested Windows 10 with Oracle JDK22, OpenJDK22, OpenJDK17

      A DESCRIPTION OF THE PROBLEM :
      Most documentation suggests that date format MMM is a 3 letter version of the month. This is not the case in English :- JDK returns 11 of the months as 3 characters, but September as 4 letters: "Sept". I cannot imagine why English MMM uses "Sept" for September. This makes exchanging dates in applications unreliable - reading and formatting dates with month abbreviation needs to pre-process text by String.replace("Sept","Sep") one way or the other.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run attached code example. Output will show MMM month format for UK and US and tries to parse a date in format "dd MMM yyyy"

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      There should not be any exception and it should print "MMM#9 UK=Sep US=Sep"
      MMM#1 UK=Jan US=Jan
      MMM#2 UK=Feb US=Feb
      MMM#3 UK=Mar US=Mar
      MMM#4 UK=Apr US=Apr
      MMM#5 UK=May US=May
      MMM#6 UK=Jun US=Jun
      MMM#7 UK=Jul US=Jul
      MMM#8 UK=Aug US=Aug
      MMM#9 UK=Sep US=Sep
      MMM#10 UK=Oct US=Oct
      MMM#11 UK=Nov US=Nov
      MMM#12 UK=Dec US=Dec
      str1=20 Sept 23
      str2=20 Sep 23
      dt2=2023-09-20
      dt1=2023-09-20

      ACTUAL -
      MMM#1 UK=Jan US=Jan
      MMM#2 UK=Feb US=Feb
      MMM#3 UK=Mar US=Mar
      MMM#4 UK=Apr US=Apr
      MMM#5 UK=May US=May
      MMM#6 UK=Jun US=Jun
      MMM#7 UK=Jul US=Jul
      MMM#8 UK=Aug US=Aug
      MMM#9 UK=Sept US=Sep
      MMM#10 UK=Oct US=Oct
      MMM#11 UK=Nov US=Nov
      MMM#12 UK=Dec US=Dec
      str1=20 Sept 23
      str2=20 Sep 23
      dt2=2023-09-20
      Exception in thread "main" java.time.format.DateTimeParseException: Text '20 Sep 23' could not be parsed at index 3
              at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2108)
              at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:2010)
              at java.base/java.time.LocalDate.parse(LocalDate.java:435)
              at DateProblem.main(DateProblem.java:52)

      ---------- BEGIN SOURCE ----------
      /**
       * UK date formats with MMM are 3 letters long for all months except September
       */
      public class DateProblem
      {
          public static void main(String... args)
          {
              final ZoneId gmt = ZoneId.of("GMT");

              final DateTimeFormatter fmtMMM = DateTimeFormatter.ofPattern("MMM").withZone(gmt);
              final DateTimeFormatter fmtMMM1 = fmtMMM.withLocale(Locale.UK);
              final DateTimeFormatter fmtMMM2 = fmtMMM.withLocale(Locale.US);

              // For me: Locale.getDefault().equals(Locale.UK) is true
              // System.out.println("UK? "+Locale.getDefault().equals(Locale.UK));

              for (int i = 1; i <= 12 ; i++)
              {
                  LocalDate d = LocalDate.of(2024, i, 28);
                  System.out.println("MMM#"+i+" UK="+fmtMMM1.format(d)+" US="+fmtMMM2.format(d));
              }

              // Note: RFC_1123_DATE_TIME does use "Sep"
      // DateTimeFormatter rfc1123 = DateTimeFormatter.RFC_1123_DATE_TIME.withLocale(Locale.UK);
      // for (int i = 1; i <= 12 ; i++)
      // {
      // ZonedDateTime dt = LocalDateTime.of(2024, i, 28, 12, 34, 56).atZone(gmt);
      // System.out.println("RFC_1123_DATE_TIME#"+i+" is "+rfc1123.format(dt));
      // }

              DateTimeFormatter ddMMMyyyy = DateTimeFormatter.ofPattern("dd MMM yy").withZone(gmt);
              DateTimeFormatter ddMMMyyyy1 = ddMMMyyyy.withLocale(Locale.UK);
              DateTimeFormatter ddMMMyyyy2 = ddMMMyyyy.withLocale(Locale.US);

              final LocalDate dtSep20th2023 = LocalDate.of(2023,9,20);
              final String strSep20th2023 = "20 Sep 23";

              String str1 = ddMMMyyyy1.format(dtSep20th2023);
              System.out.println("str1="+str1);
              String str2 = ddMMMyyyy2.format(dtSep20th2023);
              System.out.println("str2="+str2);

              LocalDate dt2 = LocalDate.parse(strSep20th2023, ddMMMyyyy2);
              System.out.println("dt2="+dt2);
              LocalDate dt1 = LocalDate.parse(strSep20th2023, ddMMMyyyy1);
              System.out.println("dt1="+dt1);
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Dates in string format have to undergo String replacement .replace("Sept","Sep") or .replace("Sep","Sept").

      FREQUENCY : always


            tongwan Andrew Wang
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: