I. Internationalization, localization, globalization

Many developers have experienced that a few years ago, the official websites of some enterprises, institutions and schools would ask: “Translate, also make an English version”, and the result would often be to maintain a separate set of English pages.

In today’s world of software development, where more and more products need to be sold overseas, that simplistic approach doesn’t apply. This requires the flexibility to adapt the software to the language, regional differences, and technical needs of the target market.

This article attempts to give a brief introduction to related concepts, especially in the field of Web front-end applications.

1.1 the term

Similar terms are often used when talking about internationalization:

  • [internationalization] : Internationalization, abbreviated as I18N because there are 18 letters between the first and last letters; The process of decoupling software from a particular language or locale. When the software is ported to different languages and regions, the software itself does not require internal engineering changes or modifications
  • [localization] : localization, referred to as L10n for the same reason; The process of translating documents for a particular locale and applying special layouts, adding local specialized parts, etc. to make the software usable in that locale or locale
  • 9. Globalization is sometimes used as a combination of the two factors mentioned above; It’s also called G11N for short

Simply put: international stage, local opera. Internationalization means a product has the “potential” to be used everywhere; Localization is the addition of features that are more suitable for use in “specific” places. For a product, internationalization only needs to be done once, but localization needs to be done once for different regions. The two are complementary and together make a system that works everywhere.

1.2 Characteristics of internationalization

An internationalized piece of software has the following characteristics:

  • It can be localized quickly
  • With localized data, the same program can run anywhere in the world
  • Text elements, such as status hints and titles in interfaces, are not hard-coded into the software, but are stored outside the source code and can change dynamically
  • New languages can be added without recompiling the software
  • The presentation of information, such as currency and date, is appropriate for the user’s location and language

1.3 Elements to be localized

In addition to the currency and date mentioned above, there are many other elements related to culture, region, and language, such as:

  • Writing direction
  • voice
  • color
  • graphics
  • icon
  • time
  • digital
  • To measure the
  • The phone number
  • honorific
  • title
  • The postal address
  • paging
  • Sorting method
  • Input processing
  • dialect
  • Laws and regulations
  • Ethics and Habits

II. Regional Settings

In addition to strange names like I18n, L10N, and G11n, locale is also commonly used, and its values are zh-cn and en-us.

A locale object is a special identifier that combines the language and locale

The locale by “of” the Internet engineering task force (IETF) “BCP 47” document series (tools.ietf.org/html/bcp47) definition.

Its common typical form consists of two parts representing language and region respectively, with a – link; You can also omit the region.

For example:

locale code Common meaning
en English
en-US English spoken in America
en-GB English spoken in Britain
zh-CN Simplified Chinese
zh-HK Traditional Chinese in Hong Kong
zh-TW Traditional Chinese in Taiwan
zh-SG Singapore Simplified Chinese
zh-MO Traditional Chinese in Macao
es-AR Spanish spoken in Argentina
ar-001 Common Arabic
ar-AE Arabic spoken in the United Arab Emirates

2.1 Area sensitivity

In general, translate a Hello into ‘Hello’ or ‘hello’ separately, depending on the locale; But numbers, dates, money, etc., need special format, or calculation of the year number, etc., can be handled with some special classes.

Code is “locale-sensitive” if its behavior depends on locale

For example, the NumberFormat class in Java is locale sensitive; The format of the numeric return value depends on the locale: it may be 902 300 (France), 902.300 (Germany), or 902,300 (THE United States).

Of course, similar classes are now available in JS, which will be covered later.

It’s important to note that locale is just an identifier, and the actual work of identifying word boundaries, formatting, and so on is still done by locale-sensitive code modules.

2.2 Language Coding

The first part of a locale represents the language, usually consisting of two or three lower-case letters, in accordance with ISO 639 (www.loc.gov/standards/i… Standard.

Such as:

Language Code Description
de German
en English
fr French
ru Russian
ja Japanese
jv Javanese
ko Korean
zh Chinese

2.3 Area Code

The second half of the locale represents the locale, which is determined by ISO 3166 (www.chemie.fu-berlin.de/diverse/doc… Standard 2 – or 3-digit capital letters, or 3-digit numbers in accordance with UN M.49. This part is optional.

Such as:

A-2 Code A-3 Code Numeric Code Description
AU AUS 036 Australia
BR BRA 076 Brazil
CA CAN 124 Canada
CN CHN 156 China
DE DEU 276 Germany
FR FRA 250 France
IN IND 356 India
RU RUS 643 Russian Federation
US USA 840 United States

2.4 More complete definitions used less frequently

See the wiki link at the end of this article.

A language tag consists of one or more subtags separated by a hyphen. Sublabels can only be composed of basic Latin letters or numbers

In BCP 47 language markup standard, the complete sub-labels are as follows:

Child tags Whether must Whether the common explain
language is is See 2.1
extended language no no A maximum of three letters can be created. It’s not actually used yet
script no general Four letters, capital letters
region no is See 2.2
variant no no Further distinguish dialects that cannot be covered by language; It is 5 to 8 letters, or 4 letters followed by a number
extension no general Such as touThe beginning, followed by a hyphen and text () of 2 to 8 characters, is used to represent Unicode and affects locale-sensitive internationalization modules such as NumberFormat, as shown in the example below
private-use no no In order tox-Private language label starting with prefix

The most basic case is as follows:

  • hi: Hindi
  • de-AT: German used in Austria
  • zh-Hans-CN: Simplified Chinese used in China
  • zh-Hant-HK: Traditional Chinese used in Hong Kong, China
  • zh-Hans: contains bothzh-CN,zh-SG(Singapore) and other places that use simplified characters

As for extension, take this example for an intuitive look:

var date = new Date(1945.7.15);

function printDate(locale) {
    var dtf = new Intl.DateTimeFormat(
        locale,
        {era:"short"} // An options object with many parameters to set
    );
    console.log( dtf.format(date) );
}

printDate("en"); //8 15, 1945 AD
printDate('ja-JP-u-ca-japanese'); // August 15, showa 20
printDate('zh-Hant-u-ca-buddhist'); // August 15, 2488
printDate('zh-Hans-u-nu-thai-ca-japanese'); // Hirowa ๒๐ ๘ month danjun ๕
printDate("zh-Hans-u-nu-fullwide-ca-persian"); // May 24, 1324 in the Persian calendar
printDate('zh-T' + 'W-u-ca-r' + 'oc'); // You can try this for yourself
Copy the code

Simply put, the form is u- followed by the free combination of nu- and CA -, which indicate which language number and Calendar comply with respectively. For the available values, see the intl.dateTimeFormat page on the MDN.

No fear of heaven, no fear of earth, just fear that southerners speak Erhua

III. Character encoding

Now do web front-end development, with the improvement of tools, framework and the popularity of standards, has been less “Chinese garble” situation, but this used to be before and after the situation is often encountered; This is where you need to understand character encodings and convert or declare them in cases where internationalization is required.

At the beginning of computer design, many countries, many different language application scenarios were not considered. The ASCII code was defined to represent letters, numbers, and other symbol numbers in 7-bit binary numbers. Later, the computer began to be popular in the world, in order to adapt to a variety of characters, a variety of coding formats, such as Chinese characters generally used in the coding format GB2312, GBK.

As a result, there is a problem that different character encodings cannot recognize each other. Unicode encodings came into being. It sets a uniform and unique binary code for each character in each language.

However, Unicode also has a disadvantage: in order to support characters of all languages, it needs to be represented by more digits. For example, ASCII requires only one byte to represent an English character, while Unicode requires two bytes. Obviously, a large number of characters can be inefficient.

To solve this problem, some intermediate character encodings have emerged: the common UTF-8, as well as UTF-16 and UTF-32.

Iv. internationalization in Java

Yellowed photographs old letters and faded Christmas cards written for you when I was young... There are already full-fledged I18N schemes in Java codeCopy the code

The reason I mention internationalization in Java, the “old backend language”, is because its solution is similar to the internationalization of later tools/frameworks such as jQuery and vue.js, And the new ECMAScript Internationalization API.

4.1 Resource Files

Java stores text in different languages in files with the suffix.properties in the format < resource name >_< language code >_< country/region code >.properties

Where, language code and country/region code are optional; An internationalized resource file named < resource name >.properties is the default resource file.

Note that this connection is made with _, which is slightly different from the standard -.

# MessagesBundle.properties
greetings = Hello.
farewell = Goodbye.
inquiry = How are you?
Copy the code
# MessagesBundle_zh_CN.properties't = hey! Farewell = Farewell! Inquiry = Have you eaten?Copy the code

Note: If the Chinese resource file is ASCII encoded, it needs to be converted to Unicode encoding using Native2ASCII

4.2 Selecting and loading languages

In Java, a java.util.Locale object is used to select the Locale; And Java. Util. ResourceBoundle is used to load the localized resource files.

import java.util.Locale;
import java.util.ResourceBundle;

public class I18NSample {

   static public void main(String[] args) {

      String language;
      String country;

      if(args.length ! =2) {
          language = new String("en");
          country = new String("US");
      } else {
          language = new String(args[0]);
          country = new String(args[1]);
      }

      Locale currentLocale;
      ResourceBundle messages;

      currentLocale = new Locale(language, country);
      messages = ResourceBundle.getBundle("MessagesBundle",currentLocale);

      System.out.println(messages.getString("greetings"));
      System.out.println(messages.getString("inquiry"));
      System.out.println(messages.getString("farewell"));
      System.out.println("-- -- -- -- --"); }}Copy the code

This procedure is easy to understand, according to the operation parameters to choose different language packages, and take out the corresponding fields.

javac I18NSample.java

java I18NSample
//Hello.
//How are you?
//Goodbye.

java I18NSample zh CN
/ / hi!
// Did you eat?
/ / see you!
Copy the code

4.3 Internationalizing tool Classes

Several locale sensitive internationalization formatting utility classes are also available in Java. For example, NumberFormat, DateFormat, and MessageFormat

import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Date;
import java.util.GregorianCalendar;
import java.text.NumberFormat;
import java.text.DateFormat;
import java.text.MessageFormat;

public class I18NSample2 {

   static public void main(String[] args) {

    double num = 123456.78;
    NumberFormat format = NumberFormat.getCurrencyInstance(Locale.SIMPLIFIED_CHINESE);
    System.out.format("Localization of %f (%s) result: %s\n", num, Locale.SIMPLIFIED_CHINESE, format.format(num));
    // 123456.780000 localization (zh_CN) result: ¥123,456.78


    Date date = new Date();
    
    DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.JAPANESE);
    System.out.format("Localization of %s (%s) result: %s\n", date, Locale.JAPANESE, df.format(date));
    // Wed Oct 10 23:25:33 CST 2018 localization (JA) result: 2018/10/10
    
    DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.SIMPLIFIED_CHINESE);
    System.out.format("Localization of %s (%s) result: %s\n", date, Locale.SIMPLIFIED_CHINESE, df2.format(date));
    // Wed Oct 10 23:25:33 CST 2018 localise (zh_CN) result: Oct 10, 2018

    
    Object[] params = {"Jack".new GregorianCalendar().getTime(), 8888};

    String pattern1 = "{0}, hello! You spend {2} dollars at {1}.";
    String msg1 = MessageFormat.format(pattern1, params);
    System.out.println(msg1);
    // Hello, Jack! You spent 8,888 yuan at 11:25 PM on 10/10, 2018.

    String pattern2 = "At {1,time,short} On {1,date,long}, {0} paid {2,number, currency}.";
    MessageFormat mf = new MessageFormat(pattern2, Locale.US);
    String msg2 = mf.format(params);
    System.out.println(msg2);
    // At 11:25 PM On October 10, 2018, Jack paid $8,888.00}}Copy the code

The Gregorian Calendar, the standard name of the Gregorian calendar, is a calendar originating from the Western society. So named because it was promulgated by Pope Gregory XIII in 1582. And AD is “Gregorian era”, also known as “western yuan”. — Baidu Encyclopedia

First GregorianCalendar this class named explanation above, of course, write internationalization code when listening to the UK that Gregorian Pope choir is also very good ~

Second, in MessageFormat, we see placeholders in the message template string. Its rules are roughly as follows:

  1. Replace the actual values passed in by the numbers in curly braces
  2. The number position can be specified arbitrarily, and the same number can appear more than once
  3. The complete format of curly braces is{ ArgumentIndex , FormatType , FormatStyle }, the latter two are optional
  4. FormatTypeThe value can be number, date, time, etc
  5. FormatStyleIt can be short, medium, long, full, INTEGER, currency, percent, and so on

V. Internationalization in jQuery

As one of the most important early tools to drive web front-end development, jQuery is the standard of the time.

When dealing with internationalization requirements, jQuery itself does not contain relevant modules. One of the most widely used third-party lightweight plug-ins is jquery.i18n.properties.

5.1 jQuery.i18n.propertiesThe characteristics of

  • Just like in Java,jQuery.i18n.propertiesusing.propertiesThe file internationalizes the JavaScript code. This approach also provides convenience when sharing resource files between Java programs and front-end JavaScript programs.
  • The resource file is named< resource name >_< language code >-< country code >.propertiesWhere language and region are used-Connect for compatible browsers bynavigator.languagejQuery.i18n.browserLang()Locale value that you get
  • You can use placeholders in resource strings (e.g. Hello = hello {0}! Today it’s {1}.)
  • The Key in the resource file supports namespaces (for example, com.any.msgs. Hello = hello!)
  • Supports cross-line values in resource files
  • Support for using keys in resource files as JavaScript variables (or functions) or maps

5.2 Basic Usage

jQuery.i18n.properties({ 
   name:'strings'// Resource file name path:'bundle/'// Resource file path mode:'both',// Schema: variable or Map language:'pt_PT'// The corresponding language cache:false, // Whether the browser caches the resource file.'UTF-8', // code. The default is UTF-8 callback:function() {// callback method}});Copy the code

In the callback callback, the · jquery.i18n.prop (key) method can be called. This method uses the values in the resource file as a map, where key refers to the key in the resource file. Use jquery.i18n. prop(key, VAR1, VAR2…) when the value specified by key contains placeholders. Where var1,var2… Replace each placeholder in turn.

Internationalization in vi.vue.js

With the advent of Angular, React, and vue.js development tools as indicators, the three cogs have ushered in a new era of front-end and back-end separation. More development logic has been transferred from the back-end to the front-end, resulting in more internationalization requirements and higher requirements for flexibility and ease of use.

This section uses vue.js as an example to analyze its common I18N solutions.

Vue-i18n (kazupon.github. IO /vue-i18n/) is a popular vue.js internationalization plug-in. Its main features include:

  • Localization of various formats
  • Support language rules such as Pluralization
  • DateTime localization
  • Number the localization
  • Component-based localization
  • Component Interpolation
  • Fallback localization

6.1 Basic Usage

<div id="app">
  <p>{{ $t("message.hello") }}</p>
</div>
Copy the code


import Vue from 'vue'
import VueI18n from 'vue-i18n'

// Register the plug-in
Vue.use(VueI18n)

// Multilingual information
// Generally can be separately modularized, such as i18n.js file
const messages = {
  en: {
    message: {
      hello: 'hello world'}},ja: {
    message: {
      hello: 'Kosher view of the world'}}}// Pass in an options to create a VueI18n instance
const i18n = new VueI18n({
  locale: 'ja'.// Set the locale
  messages, 
})

// Pass i18n in the Vue instantiation option
new Vue({ i18n }).$mount('#app')
Copy the code


Output:<p>Attraction is reflected in the world</p>
Copy the code

As you can see, vue.js no longer relies on.properties resource files, but instead uses js objects or modularity.

6.2 Multilingual Resource syntax

In addition to simple key-value pairs, vue.js supports a variety of flexible syntax:

{
  "en": {  / / English
      "key1": "this is message1".// Basic key-value pairs
      "nested": { / / nested
        "message1": "this is nested message1"
      },
      "errors": [ // Array, which can hold various values
        "this is 0 error code message",
        {"internal1": "this is internal 1 error message"},"this is nested array error 1"]],// Common words can be spliced together
      "the_world": 'the world'."dio": 'DIO:'."linked": '@:message.dio @:message.the_world !!!! '
  },
  "ja": { / / Japanese
    // ...}}Copy the code


<p>{{ $t('key1') }}</p>
<p>{{ $t('nested.message1') }}</p>
<p>{{ $t('errors[0]') }}</p>
<p>{{ $t('errors[1].internal1') }}</p>
<p>{{ $t('errors[2][0]') }}</p>

<p>{{ $t('message.linked') }}</p>
Copy the code

6.3 a placeholder

The traditional placeholder form, known here as List formatting:

<p>{{$t('message.hello', 'message.hello')}}</p>
Copy the code


const messages = {
  en: {
    message: {
      hello: '{0} world, I am {1}'}},zh: {
    message: {
      hello: 'I am {1}, the world, {0}! I am a {1}! '}}}const i18n = new VueI18n({
  locale: 'zh',
  messages
})
Copy the code


Output:<p>I am Xiao Ming, hello world! I'm Xiao Ming!</p>
Copy the code

Also supports the form of passing key values, called “Named formatting” :

<p>$t('message.goodbye', {day: "tomorrow "})}}</p>
Copy the code


const messages = {
  zh: {
    message: {
      hello: 'I am {1}, the world, {0}! I am a {1}! '.goodbye: 'goodbye! {day} to see! '}}}Copy the code


Output:<p>Good bye! See you tomorrow!</p>
Copy the code

6.4 DateTime localization

<p>{{ $d(new Date(1945,7,15)) }}</p>
<p>{{$d(new Date(1945,7,15), 'config2', 'ja-jp ')}}</p>
Copy the code


const dateTimeFormats = {
  'en-US': {},'ja-JP': {
    config1: {
      year: 'numeric'.month: 'short'.day: 'numeric'
    },
    config2: {
      year: 'numeric'.month: 'short'.day: 'numeric'.weekday: 'short'.hour: 'numeric'.minute: 'numeric'.hour12: true.era: 'short'}}}const messages = {
  en: {},ja: {}}const i18n = new VueI18n({
  locale: 'ja'.// Set the locale
  messages, 
  dateTimeFormats // Pass in a date-time format
})
Copy the code


Output:<p>1945/8/15</p>
<p>Gregorian calendar August 15, 1945 0:00 A.M</p>
Copy the code

The syntax is shown in the code. For details about configuration items, see www.ecma-international.org/ecma-402/2.

6.5 Localization of Number

<p>{{ $n(100, 'currency') }}</p>
<p>{{ $n(100, 'currency', 'ja-JP') }}</p>
Copy the code


const numberFormats = {
   'en-US': {
     currency: {
       style: 'currency'.currency: 'USD'}},'ja-JP': {
     currency: {
       style: 'currency'.currency: 'JPY'.currencyDisplay: 'symbol'}}}const messages = {
  en: {},ja: {}}const i18n = new VueI18n({
  locale: 'ja'.// Set the locale
  messages, 
  numberFormats // Pass in one more number format
})
Copy the code


Output:<p>The $100.00</p>
<p>Selections of 100</p>
Copy the code

The syntax is also easy to understand. For specific configuration items, see developer.mozilla.org/en-US/docs/…

6.6 Component-based I18N

In addition to passing the internationalization setting as a constructor parameter in the root instance of the Vue, i18N can also be set on individual Vue components, whose scope is limited to the component itself, and fields with global internationalization duplication are prefered.

<div id="app">
  <p>{{ $t("message.hello") }}</p>
  <component1></component1>
</div>
Copy the code


Vue root instance and global 'i18n'
const i18n = new VueI18n({
  locale: 'ja'.messages: {
    en: {
      message: {
        hello: 'hello world'.greeting: 'good morning'}},ja: {
      message: {
        hello: 'Kosher view of the world'.greeting: 'お snows snows and joins us solely '}}}})// Define the component
const Component1 = {
  template: ` 
      

Component1 locale messages: {{ $t("message.hello") }}

Fallback global locale messages: {{ $t("message.greeting") }}

`
.i18n: { // local 'i18n' messages: { en: { message: { hello: 'hello component1'}},ja: { message: { hello: 'Kosher view of the spring, Component1' } } } } } new Vue({ i18n, components: { Component1 } }).$mount('#app') Copy the code


Output:<div id="app">
  <p>Attraction is reflected in the world</p>
  <div class="container">
    <p>Component1 locale messages: Kosher messages, Component1</p>
    <p>Fallback Global Locale messages: お Scot Becomes air on Mars and skateboard</p>
  </div>
</div>
Copy the code

6.7 Component Interpolation

Sometimes the operation fails, refer to localization information such as {0} page or total amount: {0} meta.

An intuitive approach might be to splice them together as several paragraphs, bypassing the HTML part; Or inject it as a whole with V-html =”$t(‘ XXX ‘)”.

But both of these measures are cumbersome and unelegant, or they carry XSS risks.

In VUE-I18N, Component interpolation can better solve this problem:

<div id="app">
  
  <i18n path="info" tag="p">
    <span place="limit"> <! -- Notice the application of the place attribute -->
      {{ changeLimit }}</span>
    <a place="action" 
       :href="changeUrl">
      {{ $t('change') }}</a>
  </i18n>
  
</div>
Copy the code


const messages = {
  en: {
    info: 'You can {action} until {limit} minutes from departure.'.change: 'change your flight'}}const i18n = new VueI18n({
  locale: 'en',
  messages, 
})

new Vue({
  i18n,
  data: {
    changeUrl: '/change'.changeLimit: 15
  }
}).$mount('#app')
Copy the code


Output:<div id="app">
    <p>
        You can 
        <a place="action" href="/change">change your flight</a> 
        until 
        <span place="limit">15</span> 
        minutes from departure.
    </p>
</div>
Copy the code

6.8 i18next

Another excellent vue.js internationalization plug-in is i18Next (github.com/i18next/i18…). , this article will not expand the introduction

VII. New JS internationalization API

ECMA International released the first version of the Standard ECMA-402 Standard, known as the ECMAScript Internationalization API, in late 2012. This standard compensates for the long overdue support for localization in ECMAScript. Almost all modern browsers already support the API.

7.1 IntlGlobal object

The Intl object is a namespace of the ECMAScript internationalization API that provides precise string comparison, number formatting, and date and time formatting. The constructors for Collator, NumberFormat, and DateTimeFormat objects are attributes of Intl objects.

  • Intl.CollatorConstructor of collators, an object used to enable language-sensitive string comparisons.
  • Intl.DateTimeFormatConstructor for an object that enables language-sensitive date and time formats.
  • Intl.NumberFormatConstructor for objects that enable language-sensitive number formats.
  • Intl.PluralRulesConstructor for objects that enable multiple sensitive formats and language rules for multiple languages.

As we’ve seen in the DateTimeFormat example in 2.3, these constructors all use the same pattern to identify locale and determine which language format to use: they all take locales and options arguments.

The options argument must be an object whose property values vary between constructors and methods. If options is not provided or is undefined, all property values are used by default.

Let’s look at a few more simple examples:

var number = 123456.789;

// German uses a comma as a decimal point. As a thousand separator
console.log(new Intl.NumberFormat('de-DE').format(number));
/ / - 123.456, 789

// Request by nu extension key in numbering system, such as Chinese decimal number
console.log(new Intl.NumberFormat('zh-Hans-CN-u-nu-hanidec').format(number));
// → one, two, three, four, six. The 789


// In German, a uses the sort of a
console.log(new Intl.Collator('de').compare('ä'.'z'));
// → -1

// In Swedish, a comes after z
console.log(new Intl.Collator('sv').compare('ä'.'z'));
/ / - 1


var date = new Date(Date.UTC(2012.11.20.3.0.0));

// Use 24-hour system
options = {
  year: 'numeric'.month: 'numeric'.day: 'numeric'.hour: 'numeric'.minute: 'numeric'.second: 'numeric'.hour12: false
};
console.log(date.toLocaleString('en-US', options));
/ / - "12/19/2012, 19:00:00"
Copy the code

7.2 intl.js polyfill

For older browsers that don’t have a native Intl API, use github.com/andyearnsha… Achieve support for most functions.

7.3 Appendix: A method for obtaining lunar dates

Before the new API, calculating the lunar calendar was difficult and had a maximum year limit; Adopting the new API is a good way to solve this problem.

The following method is modified from jsfiddle.net/DerekL/mGXK…

function getLunarDate(date) {
  const TIAN_GAN = ["甲"."乙"."丙"."Ding"."戊"."己"."庚"."Xin"."壬"."癸"];
  const DI_ZHI = ["Child"."Ugly"."Yin"."Frame"."Chen"."The third"."Noon"."Not"."" "."Unitary"."Xu-gou"."Hai"];
  const SHI = ["Early"."Ten"."21"."Three"];
  const YUE = [""."Ten"];
  const GE = ["一"."二"."Three"."Four"."Five"."Six"."Seven"."Eight"."Nine"."Ten"];
  
  const locale = "zh-TW-u-ca-chinese";
  const fmt = (key, d=null) = >{
  	return Intl.DateTimeFormat(locale,{[key]:"numeric"}).format(d||date).match(/\d+/) [0];
  };
  const isLeapMonth = (d) = >{
  	let _date = new Date(date);
    _date.setDate(-d);
    return fmt("month", _date) === m;
  };
  
  let y = fmt("year");
  let m = fmt("month");
  let d = fmt("day");

  isL = isLeapMonth(d);

  y = TIAN_GAN[(y - 1) % 10]
  	+ DI_ZHI[(y - 1) % 12];
  m = (YUE[(m - 1) / 10 | 0]
  	+ GE[(m - 1) % 10]).replace($/ / ^."Is");
  d = (SHI[(d) / 10 | 0]
  	+ GE[(d - 1) % 10]).replace($/ / ^ ShiShi."The 10th").replace(/ ^ 10 $20 /."Twenty");

  return y + "Year" + (isL ? "Leap" : "") + m + "Month" + d;
}

var date = new Date(1945.7.15);
var lunar = getLunarDate(date);
console.log(lunar); // July 8, yiyou
Copy the code

VIII. Reference materials

  • Github.com/kazupon/vue…
  • Docs.oracle.com/javase/tuto…
  • www.ibm.com/developerwo…
  • www.jianshu.com/p/09edb0a1c…
  • www.ibm.com/developerwo…
  • zh.wikipedia.org/wiki/ Internationalization vs. local…
  • Developer.mozilla.org/zh-CN/docs/…
  • baike.baidu.com/item/ Intna Schonner
  • Formatjs. IO/guides/basi…
  • Zh.wikipedia.org/wiki/IETF language…
  • www.huahuaxie.com/android-int…
  • www.zhihu.com/question/21…
  • Itfish.net/article/386…
  • Userguide.icu-project.org/formatparse…
  • www.ibm.com/developerwo…
  • Jsfiddle.net/DerekL/mGXK…
  • Blog.csdn.net/PacosonSWJT…

— End —