Java Localization



Java SE 11 Developer certification (exam number 1Z0-819) here

Localization

Date and time management

Java 8 comes with a new API (java.time package) to deal with dates, times…

For convenience, dates and times have, from an I/O perspective in particular, to be convertible to strings (human-readable format). To that extent, formats may also guide the conversion of strings into computable date/time formats based on java.time.format.DateTimeFormatter.

Example (old-school style)

public class Leap_year_UTILITY {

    public static String Leap_year(final String date) throws Exception {
        java.util.Calendar calendar = java.util.Calendar.getInstance();
        calendar.setTime(new java.text.SimpleDateFormat("yyyy-MM-dd").parse(date));
        return " (before Java 8) " + (new java.util.GregorianCalendar()).isLeapYear(calendar.get(java.util.Calendar.YEAR));
    }
}

Example (java.time API)

public class Leap_year_UTILITY {

    public static String Leap_year_(final String date) throws Exception {
        // 'java.time.format.DateTimeFormatter.ISO_LOCAL_DATE' => "2020-04-15"
        java.time.LocalDate locale_date = java.time.LocalDate.parse(date, java.time.format.DateTimeFormatter.ISO_LOCAL_DATE);
        // return " (from Java 8) " + java.time.Year.isLeap(locale_date.getYear());
        return " (from Java 8) " + locale_date.isLeapYear();
    }
}

Time zones, internationalization…

Rules

Example Localization.Java.zip 

java.time.ZonedDateTime yesterday = java.time.LocalDateTime.now()
                .minusDays(1L)
                .atZone(java.time.ZoneId.systemDefault());
System.out.println("Yesterday: " + java.time.format.DateTimeFormatter.ISO_LOCAL_DATE.format(yesterday));
java.time.ZonedDateTime tomorrow = java.time.LocalDateTime.now()
                .plusDays(1L)
                .atZone(java.time.ZoneId.of("Europe/Paris"));
System.out.println("Tomorrow: " + java.time.format.DateTimeFormatter.ofPattern("EEE, d MMM yyyy", java.util.Locale.FRENCH).format(tomorrow));
java.time.ZonedDateTime next_friday = java.time.LocalDateTime.now()
                .with(java.time.temporal.TemporalAdjusters.next(java.time.DayOfWeek.FRIDAY))
                .atZone(java.time.ZoneId.of("Europe/Paris"));
System.out.println("Next friday: " + java.time.format.DateTimeFormatter.ofLocalizedDate(java.time.format.FormatStyle.SHORT).format(next_friday));

Display

Yesterday: 2022-10-02
Tomorrow: mar., 4 oct. 2022
Next friday: 07/10/2022

Example (all time zones) Localization.Java.zip 

for (String id : java.util.TimeZone.getAvailableIDs()) {
    System.out.println('\t' + id);
}
// I live in France:
java.util.TimeZone time_zone = java.util.TimeZone.getDefault();
assert (time_zone.getID().equals(java.util.TimeZone.getTimeZone("Europe/Paris").getID()));
System.out.println(time_zone.getDisplayName()); // "Heure d'Europe centrale"

Example (compute seasons) Heatwave.Java.zip 

public enum Cities {
    Paris("Europe/Paris"), Sydney("Australia/Sydney"); // Id. of time zones...
    private final String _literal;
    Cities(String literal) { _literal = literal; }
    @Override
    public String toString() { return _literal; }
}

public enum Seasons {Summer, Autumn, Winter, Spring, Unknown}

public static Seasons Season(java.time.ZonedDateTime date_time) {
   /* One deals with Paris and Sydney only: (!Paris => Sydney), which is equivalent to (Paris || !Sydney) */
    assert (date_time.getZone().getId().equals(Cities.Paris) || !date_time.getZone().getId().equals(Cities.Sydney));

    int day = date_time.getDayOfMonth(); // [1 - 31]
    java.time.Month month = date_time.getMonth(); // Type énuméré...
    switch (month) {
         case JULY:
         case AUGUST:
            return date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Summer : Seasons.Winter;
        case SEPTEMBER:
            return (day < 21)
                    ? date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Summer : Seasons.Winter
                    : date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Autumn : Seasons.Spring;
        case OCTOBER:
        case NOVEMBER:
            return date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Autumn : Seasons.Spring;
        case DECEMBER:
            return (day < 21)
                    ? date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Autumn : Seasons.Spring
                    : date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Winter : Seasons.Summer;
        case JANUARY:
        case FEBRUARY:
            return date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Winter : Seasons.Summer;
        case MARCH:
            return (day < 21)
                    ? date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Winter : Seasons.Summer
                    : date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Spring : Seasons.Autumn;
        case APRIL:
        case MAY:
            return date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Spring : Seasons.Autumn;
        case JUNE:
            return (day < 21)
                    ? date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Spring : Seasons.Autumn
                    : date_time.getZone().getId().equals(Cities.Paris) ? Seasons.Summer : Seasons.Winter;
        default:
            return Seasons.Unknown;
    }
}
Internationalization

Rules

Example (texte_fr.properties file) Localization.Java.zip 

texte=Ce tutoriel traite des problèmes d'internationalisation en Java.

Example Localization.Java.zip 

// 'resources/texte_fr.properties' is in the 'classpath':
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("texte", java.util.Locale.FRANCE);
// Set project encoding to 'UTF-16' to get French accents:
System.out.println(bundle.getString("texte"));
// 'Ce tutoriel traite des problèmes d'internationalisation en Java.'

java.util.Currency EURO = java.util.Currency.getInstance(java.util.Locale.FRANCE);
java.util.Currency US_DOLLAR = java.util.Currency.getInstance(java.util.Locale.US);
System.out.println(String.format(java.util.Locale.US, "On %s, change from %s to %s is %f.", java.time.LocalDate.now(), EURO, US_DOLLAR, 0.986));
// 'On 2022-10-06, change from EUR to USD is 0.986000.'

System.out.println(java.util.Currency.getInstance(java.util.Locale.US).getSymbol(java.util.Locale.FRANCE));
// '$US'

java.text.MessageFormat message_format = new java.text.MessageFormat("On {0}, change from {1} to {2} is {3,number,percent}.", java.util.Locale.US);
System.out.println(message_format.format(new Object[]{java.time.LocalDate.now(), EURO, java.util.Currency.getInstance(java.util.Locale.US).getSymbol(java.util.Locale.FRANCE), 0.986}));
// 'On 2022-10-06, change from EUR to $US is 99%.'