Globalizing Modern Apps

by Rafael Xavier / @rxaviers / gh:rxaviers

ecma-402

Why is i18n important?

What is it about?

ICU

International Components for Unicode

icu

"format numbers javascript"

"format currencies javascript"

Intl.NumberFormat() 123,456
Intl.NumberFormat(, {style: 'currency'}) $69,900.00
Intl.DateTimeFormat() 27/10/2015
Intl.Collator() <localized comparison>
iOS Android Opera
Mobile
Node.js
Intl.NumberFormat 11+ 4.4+ ✔ (en)
Intl.DateTimeFormat 11+ 4.4+ ✔ (en)
Intl.Collator 11+ 4.4+ ✔ (en)

caniuse.com/#search=intl

iOS Android Opera
Mobile
Node.js
Intl.NumberFormat 11+ 4.4+ ✔ (en)
Intl.DateTimeFormat 11+ 4.4+ ✔ (en)
Intl.Collator 11+ 4.4+ ✔ (en)
Pluralization
Message formatting
Relative Time fmt
Unit formatting
iOS Android Opera
Mobile
Node.js
Intl.NumberFormat 11+ 4.4+ ✔ (en)
Intl.DateTimeFormat 11+ 4.4+ ✔ (en)
Intl.Collator 11+ 4.4+ ✔ (en)
Pluralization
Message formatting
Relative Time fmt
Unit formatting
Abbreviation
Text segmentation

JavaScript Libraries

JavaScript Libraries

Comparison Grid

github.com/rxaviers/javascript-globalization/

  • Always up-to-date (CLDR as a peer dependency)
  • Quick development (declarative code)
  • Smallest and fastest bundles (optimization for production)

Library Foo


.
└── dist
    ├── ar.js
    ├── de.js
    ├── en-GB.js
    ├── en.js
    ├── es.js
    ├── zh.js
    └── zh-TW.js
		

Library Foo


.  // library foo at version X
└── dist
    ├── ar.js     // contains CLDR at version Y
    ├── de.js     // contains CLDR at version Y
    ├── en-GB.js  // contains CLDR at version Y
    ├── en.js     // contains CLDR at version Y
    ├── es.js     // contains CLDR at version Y
    ├── zh.js     // contains CLDR at version Y
    └── zh-TW.js  // contains CLDR at version Y
		

My application


package.json:
{
    "name": "my-application",
    "dependencies": {
        "globalize": "1.x"
    },
    "peerDependencies": {
        "cldr-data": "28"
    }
}
		

  • Always up-to-date (CLDR as a peer dependency)
  • Quick development (declarative code)
  • Smallest and fastest bundles (optimization for production)

My application


// Before we can use Globalize, we need to feed it
// on the appropriate I18n content (Unicode CLDR).
Globalize.load(
	require( "cldr-data/main/en/ca-gregorian" ),
	require( "cldr-data/main/en/dateFields" ),
	require( "cldr-data/main/en/numbers" ),
	require( "cldr-data/supplemental/likelySubtags" ),
	require( "cldr-data/supplemental/timeData" ),
	require( "cldr-data/supplemental/weekData" )
);

// Set the default locale.
Globalize.locale( "en" );

// Use Globalize to format dates.
Globalize.formatDate( new Date(), { datetime: "medium" } );
		

My application


// Use Globalize to format dates.
Globalize.formatDate( new Date(), { datetime: "medium" } );
		

  • Always up-to-date (CLDR as a peer dependency)
  • Quick development (declarative code)
  • Smallest and fastest bundles (optimization for production)

Currency codes


ADP, AED, AFA, AFN, ALK, ALL, AMD, ANG, AOA, AOK, AON, AOR, ARA, ARL, ARM, ARP, ARS, ATS, AUD, AWG,
AZM, AZN, BAD, BAM, BAN, BBD, BDT, BEC, BEF, BEL, BGL, BGM, BGN, BGO, BHD, BIF, BMD, BND, BOB, BOL,
BOP, BOV, BRB, BRC, BRE, BRL, BRN, BRR, BRZ, BSD, BTN, BUK, BWP, BYB, BYR, BZD, CAD, CDF, CHE, CHF,
CHW, CLE, CLF, CLP, CNX, CNY, COP, COU, CRC, CSD, CSK, CUC, CUP, CVE, CYP, CZK, DDM, DEM, DJF, DKK,
DOP, DZD, ECS, ECV, EEK, EGP, ERN, ESA, ESB, ESP, ETB, EUR, FIM, FJD, FKP, FRF, GBP, GEK, GEL, GHC,
GHS, GIP, GMD, GNF, GNS, GQE, GRD, GTQ, GWE, GWP, GYD, HKD, HNL, HRD, HRK, HTG, HUF, IDR, IEP, ILP,
ILR, ILS, INR, IQD, IRR, ISJ, ISK, ITL, JMD, JOD, JPY, KES, KGS, KHR, KMF, KPW, KRH, KRO, KRW, KWD,
KYD, KZT, LAK, LBP, LKR, LRD, LSL, LTL, LTT, LUC, LUF, LUL, LVL, LVR, LYD, MAD, MAF, MCF, MDC, MDL,
MGA, MGF, MKD, MKN, MLF, MMK, MNT, MOP, MRO, MTL, MTP, MUR, MVP, MVR, MWK, MXN, MXP, MXV, MYR, MZE,
MZM, MZN, NAD, NGN, NIC, NIO, NLG, NOK, NPR, NZD, OMR, PAB, PEI, PEN, PES, PGK, PHP, PKR, PLN, PLZ,
PTE, PYG, QAR, RHD, ROL, RON, RSD, RUB, RUR, RWF, SAR, SBD, SCR, SDD, SDG, SDP, SEK, SGD, SHP, SIT,
SKK, SLL, SOS, SRD, SRG, SSP, STD, SUR, SVC, SYP, SZL, THB, TJR, TJS, TMM, TMT, TND, TOP, TPE, TRL,
TRY, TTD, TWD, TZS, UAH, UAK, UGS, UGX, USD, USN, USS, UYI, UYP, UYU, UZS, VEB, VEF, VND, VNN, VUV,
WST, XAF, XAG, XAU, XBA, XBB, XBC, XBD, XCD, XDR, XEU, XFO, XFU, XOF, XPD, XPF, XPT, XRE, XSU, XTS,
XUA, XXX, YDD, YER, YUD, YUM, YUN, YUR, ZAL, ZAR, ZMK, ZMW, ZRN, ZRZ, ZWD, ZWL, ZWR
		

Currency data for `en`


{
    ...
    "UGX": {
      "displayName": "Ugandan Shilling",
      "displayName-count-one": "Ugandan shilling",
      "displayName-count-other": "Ugandan shillings",
      "symbol": "UGX"
    },
    "USD": {
      "displayName": "US Dollar",
      "displayName-count-one": "US dollar",
      "displayName-count-other": "US dollars",
      "symbol": "$",
      "symbol-alt-narrow": "$"
    },
    "USN": {
      "displayName": "US Dollar (Next day)",
      "displayName-count-one": "US dollar (next day)",
      "displayName-count-other": "US dollars (next day)",
      "symbol": "USN"
    },
    ...
}
		

Gregorian calendar data


        "calendars": {
          "gregorian": {
            "months": {
              "format": {
                "abbreviated": {
                  "1": "Jan",
                  "2": "Feb",
                  "3": "Mar",
                  "4": "Apr",
                  "5": "May",
                  "6": "Jun",
                  "7": "Jul",
                  "8": "Aug",
                  "9": "Sep",
                  "10": "Oct",
                  "11": "Nov",
                  "12": "Dec"
                },
                "narrow": {
                  "1": "J",
                  "2": "F",
		

"July 4"

"07/04"

Gregorian calendar translations


"Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" "J" "F" "M" "A" "M" "J" "J"
"A" "S" "O" "N" "D" "January" "February" "March" "April" "May" "June" "July" "August" "September"
"October" "November" "December" "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov"
"Dec" "J" "F" "M" "A" "M" "J" "J" "A" "S" "O" "N" "D" "January" "February" "March" "April" "May"
"June" "July" "August" "September" "October" "November" "December" "Sun" "Mon" "Tue" "Wed" "Thu"
"Fri" "Sat" "S" "M" "T" "W" "T" "F" "S" "Su" "Mo" "Tu" "We" "Th" "Fr" "Sa" "Sunday" "Monday"
"Tuesday" "Wednesday" "Thursday" "Friday" "Saturday" "Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "S"
"M" "T" "W" "T" "F" "S" "Su" "Mo" "Tu" "We" "Th" "Fr" "Sa" "Sunday" "Monday" "Tuesday" "Wednesday"
"Thursday" "Friday" "Saturday" "Q1" "Q2" "Q3" "Q4" "1" "2" "3" "4" "1st quarter" "2nd quarter" "3rd
quarter" "4th quarter" "Q1" "Q2" "Q3" "Q4" "1" "2" "3" "4" "1st quarter" "2nd quarter" "3rd quarter"
"4th quarter" "midnight" "AM" "am" "noon" "PM" "pm" "in the morning" "in the afternoon" "in the
evening" "at night" "mi" "a" "am" "n" "p" "pm" "in the morning" "in the afternoon" "in the evening"
"at night" "midnight" "AM" "am" "noon" "PM" "pm" "in the morning" "in the afternoon" "in the
evening" "at night" "midnight" "AM" "am" "noon" "PM" "pm" "in the morning" "in the afternoon" "in
the evening" "at night" "midnight" "AM" "am" "noon" "PM" "pm" "in the morning" "in the afternoon"
"in the evening" "at night" "midnight" "AM" "am" "noon" "PM" "pm" "morning" "afternoon" "evening"
"night" "Before Christ" "Before Common Era" "Anno Domini" "Common Era" "BC" "BCE" "AD" "CE" "B"
"BCE" "A" "CE" "EEEE, MMMM d, y" "MMMM d, y" "MMM d, y" "M/d/yy" "h:mm:ss a zzzz" "h:mm:ss a z"
"h:mm:ss a" "h:mm a" "d" "ccc" "d E" "E h:mm a" "E HH:mm" "E h:mm:ss a" "E HH:mm:ss" "y G" "MMM y G"
"MMM d, y G" "E, MMM d, y G" "h a" "HH" "h:mm a" "HH:mm" "h:mm:ss a" "HH:mm:ss" "h:mm:ss a v"
"HH:mm:ss v" "h:mm a v" "HH:mm v" "L" "M/d" "E, M/d" "LLL" "MMM d" "E, MMM d" "MMMM d" "mm:ss" "y"
"M/y" "M/d/y" "E, M/d/y" "MMM y" "MMM d, y" "E, MMM d, y" "MMMM y" "QQQ y" "QQQQ y" "d – d" "h a – h
a" "h – h a" "HH – HH" "h:mm a – h:mm a" "h:mm – h:mm a" "h:mm – h:mm a" "HH:mm – HH:mm" "HH:mm –
HH:mm" "h:mm a – h:mm a v" "h:mm – h:mm a v" "h:mm – h:mm a v" "HH:mm – HH:mm v" "HH:mm – HH:mm v"
"h a – h a v" "h – h a v" "HH – HH v" "M – M" "M/d – M/d" "M/d – M/d" "E, M/d – E, M/d" "E, M/d – E,
M/d" "MMM – MMM" "MMM d – d" "MMM d – MMM d" "E, MMM d – E, MMM d" "E, MMM d – E, MMM d" "y – y"
"M/y – M/y" "M/y – M/y" "M/d/y – M/d/y" "M/d/y – M/d/y" "M/d/y – M/d/y" "E, M/d/y – E, M/d/y" "E,
M/d/y – E, M/d/y" "E, M/d/y – E, M/d/y" "MMM – MMM y" "MMM y – MMM y" "MMM d – d, y" "MMM d – MMM d,
y" "MMM d, y – MMM d, y" "E, MMM d – E, MMM d, y" "E, MMM d – E, MMM d, y" "E, MMM d, y – E, MMM d,
y" "MMMM – MMMM y" "MMMM y – MMMM y"
		
formatter = Globalize.numberFormatter()

10 secs

formatter( 3.141592 )

1 sec

Demo - Pure Globalize (webpack)

examples/app-npm-webpack

Demo - BTC as currency code

Demo - React.js and ES6

yarsk

Demo - Globalize + ECMA-402

Demo - Translation Table

Happy developing

Thank You

Questions?

Rafael Xavier

@rxaviers

gh:rxaviers