Localization
- Implement Localization using
java.util.Locale
, resource bundles, and Java APIs to parse and format messages, dates, and numbers
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
java.time
API intensively deals with Localization issues, usingjava.util.Locale
in particularExample 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; } }
Rules
- Beyond date and time management, internationalization relates to the possibility of dealing with cultural issues including natural languages, currencies… Accordingly, complex formatting is required to adhere to cultural common presentation
Example (
texte_fr.properties
file) Localization.Java.ziptexte=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%.'