Filipino

BCP 47 language tag: fil

Lokalized supports cardinality, cardinality range, and ordinality rules for Filipino.

Filipino is most often spoken in the Philippines, the United States, Canada, and Macao SAR China.

Cardinalities

  • CARDINALITY_ONE

    Matches v = 0 and i = 1,2,3 or v = 0 and i % 10 != 4,6,9 or v != 0 and f % 10 != 4,6,9

    Example Integers: 0, 3, 5, 7, 8, 10, 13, 15, 17, 18, 20, 21, 100, 1000, 10000, 100000, 1000000, …

    Example Decimals: 0.0, 0.3, 0.5, 0.7, 0.8, 1.0, 1.3, 1.5, 1.7, 1.8, 2.0, 2.1, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …

  • CARDINALITY_OTHER

    Matches all other values

    Example Integers: 4, 6, 9, 14, 16, 19, 24, 26, 104, 1004, …

    Example Decimals: 0.4, 0.6, 0.9, 1.4, 1.6, 1.9, 2.4, 2.6, 10.4, 100.4, 1000.4, …

Cardinality example

This localized strings file selects the localized form of “day” for a delivery estimate. Raw numbers choose the CLDR category; values formatted with the JDK NumberFormat are interpolated for display.

Sample localized strings file
fil.json Localized Strings File (Filipino)
{
  "Delivery.LeadTime": {
    "commentary": "Estimated delivery time, expressed in days.",
    "translation": "{{leadTime}}",
    "placeholders": {
      "leadTime": {
        "value": "dayCount",
        "translations": {
          "CARDINALITY_ONE": "{{formattedDayCount}} araw",
          "CARDINALITY_OTHER": "{{formattedDayCount}} na araw"
        }
      }
    }
  }
}
Usage and expected results

The Java code passes each raw number for cardinality selection and formats its display value separately with NumberFormat.

Locale locale = Locale.forLanguageTag("fil");

Strings strings = Strings.withFallbackLocale(locale)
  .localizedStringSupplier(() -> LocalizedStringLoader.loadFromFilesystem(Paths.get("strings")))
  .localeSupplier((matcher) -> matcher.bestMatchFor(locale))
  .build();

NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);

// Raw numbers select language forms; NumberFormat produces the display values

// CARDINALITY_ONE
Number oneDayCount = 0;
String oneFormattedDayCount = numberFormat.format(oneDayCount);

assertEquals(Cardinality.ONE, Cardinality.forNumber(oneDayCount, locale));

// Expected: 0 araw
assertEquals(oneFormattedDayCount + " araw", strings.get(
  "Delivery.LeadTime", Map.of("dayCount", oneDayCount, "formattedDayCount", oneFormattedDayCount)
));

// CARDINALITY_OTHER
Number otherDayCount = 4;
String otherFormattedDayCount = numberFormat.format(otherDayCount);

assertEquals(Cardinality.OTHER, Cardinality.forNumber(otherDayCount, locale));

// Expected: 4 na araw
assertEquals(otherFormattedDayCount + " na araw", strings.get(
  "Delivery.LeadTime", Map.of("dayCount", otherDayCount, "formattedDayCount", otherFormattedDayCount)
));

Cardinality Ranges

These are CLDR's explicit range mappings. For any start/end pair not listed, Cardinality.forRange(...) falls back to the ending cardinality.

  • CARDINALITY_ONE - CARDINALITY_ONE

    Matches CARDINALITY_ONE

  • CARDINALITY_ONE - CARDINALITY_OTHER

    Matches CARDINALITY_OTHER

  • CARDINALITY_OTHER - CARDINALITY_ONE

    Matches CARDINALITY_ONE

  • CARDINALITY_OTHER - CARDINALITY_OTHER

    Matches CARDINALITY_OTHER

Cardinality range example

The start and end cardinalities select the locale's CLDR range result. The selected form wraps a separately formatted display range.

Sample localized strings file
fil.json Localized Strings File (Filipino)
{
  "Delivery.Window": {
    "commentary": "Estimated delivery window, expressed as a range of days.",
    "translation": "{{window}}",
    "placeholders": {
      "window": {
        "range": {
          "start": "minDays",
          "end": "maxDays"
        },
        "translations": {
          "CARDINALITY_ONE": "{{formattedDayRange}} araw",
          "CARDINALITY_OTHER": "{{formattedDayRange}} na araw"
        }
      }
    }
  }
}
Usage and expected results

The Java code passes raw range endpoints for selection. Because NumberFormat formats one number at a time, it formats both endpoints separately and joins them for display; choose range punctuation appropriate to your application.

Locale locale = Locale.forLanguageTag("fil");

Strings strings = Strings.withFallbackLocale(locale)
  .localizedStringSupplier(() -> LocalizedStringLoader.loadFromFilesystem(Paths.get("strings")))
  .localeSupplier((matcher) -> matcher.bestMatchFor(locale))
  .build();

NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);

// Raw numbers select language forms; NumberFormat produces the display values

// CARDINALITY_ONE range
Number minDays = 0;
String formattedMinDays = numberFormat.format(minDays);
Number maxDays = 3;
String formattedMaxDays = numberFormat.format(maxDays);
String formattedDayRange = formattedMinDays + "-" + formattedMaxDays;

assertEquals(Cardinality.ONE, Cardinality.forRange(
  Cardinality.forNumber(minDays, locale),
  Cardinality.forNumber(maxDays, locale),
  locale
));

// Expected: 0-3 araw
assertEquals(formattedDayRange + " araw", strings.get(
  "Delivery.Window",
  Map.of("minDays", minDays, "maxDays", maxDays, "formattedDayRange", formattedDayRange)
));

Ordinalities

  • ORDINALITY_ONE

    Matches n = 1

    Example Integers: 1

  • ORDINALITY_OTHER

    Matches all other values

    Example Integers: 0, 2, 16, 100, 1000, 10000, 100000, 1000000, …

Addendum: Language Form Rules

The language form expressions above are specified by Unicode Technical Standard #35 and use the following notation:

  • n absolute value of the source number (integer and decimals)
  • i integer digits of n
  • v number of visible fraction digits in n, with trailing zeros
  • w number of visible fraction digits in n, without trailing zeros
  • f visible fractional digits in n, with trailing zeros
  • t visible fractional digits in n, without trailing zeros
  • c/e compact decimal exponent operands used by some CLDR compact-number rules