Skip to main content

APIzation: Replication Package

[Q#50277395][A#50277971] Java: How to display weekday, month and date and no year in locale sensitive manner

https://stackoverflow.com/q/50277395

In my app I need to display dates in a locale-sensitive manner. So "Thursday, May 10, 2018" should display as is in en_US but should display as "Thursday, 10 May 2018" in en_GB (English Great Britain). In most cases I can use the following style of code with java.time API classes: In such cases I do not specify an explicit date pattern but instead specify a symbolic FormatStyle. I am not sure of the best way to handle case where there is no standard FormatStyle that meets my needs. A concrete example is where I need to show Day of Week, Month and Date but no year. So "Thursday, May 10, 2018" should display as "Thursday, May 10" in en_US but should display as "Thursday, 10 May" in en_GB (English Great Britain). Any suggestions on how to handle this requirement?

Answer

https://stackoverflow.com/a/50277971

Output with loc equal to Locale.US: Thursday, May 10 And with Locale.UK (Great Britain): Thursday, 10 May How it works: I start out from a localized format pattern string. In my regular expression I am recognizing format pattern letters that have to do with month (ML), day of month (d) and day of week (Eec). I am keeping the substring from the first to the last of such letters. The leading reluctant quantifier .*? makes sure I get the first matching letter. If some locale puts the year somewhere between those wanted elements, it will end up being included. I am feeling I am being overly creative. Please test with all the test examples you can think of before deciding that you want something like this.

APIzation

String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
            FormatStyle.FULL, null, IsoChronology.INSTANCE, loc);
    formatPattern = formatPattern.replaceFirst("^.*?([MLdEec].*[MLdEec]).*$", "$1");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(formatPattern, loc);
    System.out.println(LocalDate.now(ZoneId.of("Pacific/Johnston")).format(dateFormatter));
package com.stackoverflow.api;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.FormatStyle;
import java.util.Locale;

public class Human50277971 {

  public static String weekdayMonthDate(Locale loc) {
    String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
      FormatStyle.FULL,
      null,
      IsoChronology.INSTANCE,
      loc
    );
    formatPattern =
      formatPattern.replaceFirst("^.*?([MLdEec].*[MLdEec]).*$", "$1");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(
      formatPattern,
      loc
    );
    return LocalDate.now(ZoneId.of("Pacific/Johnston")).format(dateFormatter);
  }
}

package com.stackoverflow.api;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.chrono.IsoChronology;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.FormatStyle;
import java.util.Locale;

/**
 * Java: How to display weekday, month and date and no year in locale sensitive manner
 *
 * @author APIzator
 * @see <a href="https://stackoverflow.com/a/50277971">https://stackoverflow.com/a/50277971</a>
 */
public class APIzator50277971 {

  public static String java(Locale loc) throws Exception {
    String formatPattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
      FormatStyle.FULL,
      null,
      IsoChronology.INSTANCE,
      loc
    );
    formatPattern =
      formatPattern.replaceFirst("^.*?([MLdEec].*[MLdEec]).*$", "$1");
    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(
      formatPattern,
      loc
    );
    return LocalDate.now(ZoneId.of("Pacific/Johnston")).format(dateFormatter);
  }
}