/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. This program is distributed in the hope *
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
* or via info@compiere.org or http://www.compiere.org/license.html *
*****************************************************************************/
package org.compiere.util;
import java.awt.ComponentOrientation;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Locale;
import java.util.logging.Logger;
import javax.print.attribute.standard.MediaSize;
import org.omidp.util.LocaleUtil;
/**
* Language Management.
*
* @author Jorg Janke
* @version $Id: Language.java,v 1.2 2006/07/30 00:52:23 jjanke Exp $
*/
public class Language implements Serializable
{
/**
*
*/
/**************************************************************************
* Languages
* http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt
* Countries
* http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm
*************************************************************************/
/**
*
*/
private static final long serialVersionUID = -964846521004545703L;
/** Base Language */
public static final String AD_Language_en_US = "en_US";
/** Additional Languages */
private static final String AD_Language_en_GB = "en_GB";
private static final String AD_Language_en_AU = "en_AU";
private static final String AD_Language_en_CA = "en_CA";
private static final String AD_Language_ca_ES = "ca_ES";
private static final String AD_Language_hr_HR = "hr_HR";
private static final String AD_Language_de_DE = "de_DE";
private static final String AD_Language_it_IT = "it_IT";
private static final String AD_Language_es_ES = "es_ES";
private static final String AD_Language_es_MX = "es_MX";
private static final String AD_Language_es_CO = "es_CO";
private static final String AD_Language_es_DO = "es_DO";
private static final String AD_Language_fr_FR = "fr_FR";
private static final String AD_Language_fr_CA = "fr_CA";
private static final String AD_Language_bg_BG = "bg_BG";
private static final String AD_Language_th_TH = "th_TH";
private static final String AD_Language_pl_PL = "pl_PL";
private static final String AD_Language_zh_TW = "zh_TW";
private static final String AD_Language_nl_NL = "nl_NL";
private static final String AD_Language_no_NO = "no_NO";
private static final String AD_Language_pt_BR = "pt_BR";
private static final String AD_Language_ru_RU = "ru_RU";
private static final String AD_Language_sl_SI = "sl_SI";
private static final String AD_Language_sr_RS = "sr_RS";
private static final String AD_Language_sv_SE = "sv_SE";
private static final String AD_Language_vi_VN = "vi_VN";
private static final String AD_Language_zh_CN = "zh_CN";
private static final String AD_Language_da_DK = "da_DK";
private static final String AD_Language_ms_MY = "ms_MY";
private static final String AD_Language_fa_IR = "fa_IR";
private static final String AD_Language_fi_FI = "fi_FI";
private static final String AD_Language_ro_RO = "ro_RO";
private static final String AD_Language_ja_JP = "ja_JP";
private static final String AD_Language_in_ID = "in_ID";
private static final String AD_Language_ar_TN = "ar_TN";
private static final String AD_Language_hu_HU = "hu_HU";
private static final String AD_Language_el_GR = "el_GR";
/***
* System Languages.
* If you want to add a language, extend the array
* - or use the addLanguage() method.
**/
static private Language[] s_languages = {
new Language ("English",
AD_Language_en_US, Locale.US, null, null,
MediaSize.NA.LETTER), // Base Language
// ordered by locale
// Not predefined Locales - need to define decimal Point and date pattern (not sure about time)
new Language ("\uFE94\uFEF4\uFE91\uFEAE\uFECC\uFEDF\uFE8D (AR)",
AD_Language_ar_TN, new Locale("ar","TN"), new Boolean(true), "dd.MM.yyyy",
MediaSize.ISO.A4),
new Language ("\u0411\u044A\u043B\u0433\u0430\u0440\u0441\u043A\u0438 (BG)",
AD_Language_bg_BG, new Locale("bg","BG"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Catal\u00e0",
AD_Language_ca_ES, new Locale("ca", "ES"), null, "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Deutsch",
AD_Language_de_DE, Locale.GERMANY, null, null,
MediaSize.ISO.A4),
new Language ("Dansk",
AD_Language_da_DK, new Locale("da","DK"), new Boolean(false), "dd-MM-yyyy",
MediaSize.ISO.A4),
new Language ("English (AU)",
AD_Language_en_AU, new Locale("en","AU"), null, "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("English (UK)",
AD_Language_en_GB, Locale.UK, null, null,
MediaSize.ISO.A4),
new Language ("English (CA)",
AD_Language_en_CA, new Locale("en","CA"), null, "MM/dd/yyyy",
MediaSize.NA.LETTER), // Canadian English
new Language ("Espa\u00f1ol",
AD_Language_es_ES, new Locale("es","ES"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Espa\u00f1ol (MX)",
AD_Language_es_MX, new Locale("es","MX"), new Boolean(true), "dd/MM/yyyy",
MediaSize.NA.LETTER),
new Language ("Espa\u00f1ol (CO)",
AD_Language_es_CO, new Locale("es","ES"), new Boolean(false), "dd/MM/yyyy",
MediaSize.NA.LETTER),
new Language ("Espa\u00f1ol (VE)",
AD_Language_es_ES, new Locale("es","ES"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Espa\u00f1ol (EC)",
AD_Language_es_ES, new Locale("es","ES"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Espa\u00f1ol (DO)",
AD_Language_es_DO, new Locale("es","DO"), new Boolean(true), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac (GR)",
AD_Language_el_GR, new Locale("el","GR"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Farsi",
AD_Language_fa_IR, new Locale("fa","IR"), new Boolean(false), "yyyy/MM/dd",
MediaSize.ISO.A4),
new Language ("Finnish",
AD_Language_fi_FI, new Locale("fi","FI"), new Boolean(true), "dd.MM.yyyy",
MediaSize.ISO.A4),
new Language ("Fran\u00e7ais",
AD_Language_fr_FR, Locale.FRANCE, null, null, // dd.MM.yy
MediaSize.ISO.A4),
new Language ("Fran\u00e7ais (CA)",
AD_Language_fr_CA, new Locale("fr","CA"), new Boolean(true), "MM/dd/yyyy", // MM/dd/yy
MediaSize.NA.LETTER),
new Language ("Hrvatski",
AD_Language_hr_HR, new Locale("hr", "HR"), null, "dd.MM.yyyy",
MediaSize.ISO.A4),
new Language ("Indonesia Bahasa",
AD_Language_in_ID, new Locale("in","ID"), new Boolean(false), "dd-MM-yyyy",
MediaSize.ISO.A4),
new Language ("Italiano",
AD_Language_it_IT, Locale.ITALY, null, null, // dd.MM.yy
MediaSize.ISO.A4),
new Language ("\u65e5\u672c\u8a9e (JP)",
AD_Language_ja_JP, Locale.JAPAN, null, null,
MediaSize.ISO.A4),
new Language ("Malaysian",
AD_Language_ms_MY, new Locale("ms","MY"), new Boolean(false), "dd-MM-yyyy",
MediaSize.ISO.A4),
new Language ("Magyar (HU)",
AD_Language_hu_HU, new Locale("hu","HU"), new Boolean(false), "yyyy.MM.dd",
MediaSize.ISO.A4),
new Language ("Nederlands",
AD_Language_nl_NL, new Locale("nl","NL"), new Boolean(false), "dd-MM-yyyy",
MediaSize.ISO.A4),
new Language ("Norsk",
AD_Language_no_NO, new Locale("no","NO"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Polski",
AD_Language_pl_PL, new Locale("pl","PL"), new Boolean(false), "dd-MM-yyyy",
MediaSize.ISO.A4),
new Language ("Portuguese (BR)",
AD_Language_pt_BR, new Locale("pt","BR"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Rom\u00e2n\u0103",
AD_Language_ro_RO, new Locale("ro","RO"), new Boolean(false), "dd.MM.yyyy",
MediaSize.ISO.A4),
new Language ("\u0420\u0443\u0441\u0441\u043a\u0438\u0439 (Russian)",
AD_Language_ru_RU, new Locale("ru","RU"), new Boolean(false), "dd-MM-yyyy",
MediaSize.ISO.A4),
new Language ("Slovenski",
AD_Language_sl_SI, new Locale("sl", "SI"), null, "dd.MM.yyyy",
MediaSize.ISO.A4),
new Language ("\u0421\u0440\u043F\u0441\u043A\u0438 (RS)",
AD_Language_sr_RS, new Locale("sr", "RS"), null, "dd.MM.yyyy",
MediaSize.ISO.A4),
new Language ("Svenska",
AD_Language_sv_SE, new Locale("sv","SE"), new Boolean(false), "yyyy-MM-dd",
MediaSize.ISO.A4),
new Language ("\u0e44\u0e17\u0e22 (TH)",
AD_Language_th_TH, new Locale("th","TH"), new Boolean(false), "dd/MM/yyyy",
MediaSize.ISO.A4),
new Language ("Vi\u1EC7t Nam",
AD_Language_vi_VN, new Locale("vi","VN"), new Boolean(false), "dd-MM-yyyy",
MediaSize.ISO.A4),
// Need to have (Windows) Asian Language Pack installed to view properly
new Language ("\u7b80\u4f53\u4e2d\u6587 (CN)",
AD_Language_zh_CN, Locale.CHINA, null, "yyyy-MM-dd",
MediaSize.ISO.A4),
new Language ("\u7e41\u9ad4\u4e2d\u6587 (TW)",
AD_Language_zh_TW, Locale.TAIWAN, null, null, // dd.MM.yy
MediaSize.ISO.A4)
};
/** Default Language */
private static Language s_loginLanguage = s_languages[0];
/** Logger */
private static Logger log = Logger.getLogger(Language.class.getName());
/**
* Get Number of Languages
* @return Language count
*/
public static int getLanguageCount()
{
return s_languages.length;
} // getLanguageCount
/**
* Get Language
* @param index index
* @return Language
*/
public static Language getLanguage (int index)
{
if (index < 0 || index >= s_languages.length)
return s_loginLanguage;
return s_languages[index];
} // getLanguage
/**
* Add Language to supported Languages
* @param language new language
*/
public static void addLanguage (Language language)
{
if (language == null)
return;
ArrayList<Language> list = new ArrayList<Language>(Arrays.asList(s_languages));
list.add(language);
s_languages = new Language[list.size()];
list.toArray(s_languages);
} // addLanguage
/**************************************************************************
* Get Language.
* If language does not exist, create it on the fly assuming that it is valid
* @param langInfo either language (en) or locale (en-US) or display name
* @return Name (e.g. Deutsch)
*/
public static Language getLanguage (String langInfo)
{
String lang = langInfo;
if (lang == null || lang.length() == 0)
lang = System.getProperty("user.language", "");
// Search existing Languages
for (int i = 0; i < s_languages.length; i++)
{
if (lang.equals(s_languages[i].getName())
|| lang.equals(s_languages[i].getLanguageCode())
|| lang.equals(s_languages[i].getAD_Language()))
return s_languages[i];
}
// Create Language on the fly
if (lang.length() == 5) // standard format <language>_<Country>
{
String language = lang.substring(0,2);
String country = lang.substring(3);
Locale locale = new Locale(language, country);
log.info ("Adding Language=" + language + ", Country=" + country + ", Locale=" + locale);
Language ll = new Language (lang, lang, locale);
// Add to Languages
ArrayList<Language> list = new ArrayList<Language>(Arrays.asList(s_languages));
list.add(ll);
s_languages = new Language [list.size()];
list.toArray(s_languages);
// Return Language
return ll;
}
// Get the default one
return s_loginLanguage;
} // getLanguage
/**
* Is it the base language
* @param langInfo either language (en) or locale (en-US) or display name
* @return true if base language
*/
public static boolean isBaseLanguage (String langInfo)
{
if (langInfo == null || langInfo.length() == 0
|| langInfo.equals(s_languages[0].getName())
|| langInfo.equals(s_languages[0].getLanguageCode())
|| langInfo.equals(s_languages[0].getAD_Language()))
return true;
return false;
} // isBaseLanguage
/**
* Get Base Language
* @return Base Language
*/
public static Language getBaseLanguage()
{
return s_languages[0];
} // getBase
/**
* Get Base Language code. (e.g. en-US)
* @return Base Language
*/
public static String getBaseAD_Language()
{
return s_languages[0].getAD_Language();
} // getBase
/**
* Get Supported Locale
* @param langInfo either language (en) or locale (en-US) or display name
* @return Supported Locale
*/
public static Locale getLocale (String langInfo)
{
return getLanguage(langInfo).getLocale();
} // getLocale
/**
* Get Supported Language
* @param langInfo either language (en) or locale (en-US) or display name
* @return AD_Language (e.g. en-US)
*/
public static String getAD_Language (String langInfo)
{
return getLanguage(langInfo).getAD_Language();
} // getAD_Language
/**
* Get Supported Language
* @param locale Locale
* @return AD_Language (e.g. en-US)
*/
public static String getAD_Language (Locale locale)
{
if (locale != null)
{
for (int i = 0; i < s_languages.length; i++)
{
if (locale.getLanguage().equals(s_languages[i].getLocale().getLanguage()))
return s_languages[i].getAD_Language();
}
}
return s_loginLanguage.getAD_Language();
} // getLocale
/**
* Get Language Name
* @param langInfo either language (en) or locale (en-US) or display name
* @return Language Name (e.g. English)
*/
public static String getName (String langInfo)
{
return getLanguage(langInfo).getName();
} // getAD_Language
/**
* Returns true if Decimal Point (not comma)
* @param langInfo either language (en) or locale (en-US) or display name
* @return use of decimal point
*/
public static boolean isDecimalPoint(String langInfo)
{
return getLanguage(langInfo).isDecimalPoint();
} // getAD_Language
/**
* Get Display names of supported languages
* @return Array of Language names
*/
public static String[] getNames()
{
String[] retValue = new String[s_languages.length];
for (int i = 0; i < s_languages.length; i++)
retValue[i] = s_languages[i].getName();
return retValue;
} // getNames
/**************************************************************************
* Get Default Login Language
* @return default Language
*/
public static Language getLoginLanguage ()
{
// return s_loginLanguage; // See bug [2946164]
return Env.getLanguage(Env.getCtx());
} // getLanguage
/**
* Set Default Login Language
* @param language language
*/
public static void setLoginLanguage (Language language)
{
if (language != null)
{
s_loginLanguage = language;
log.config(s_loginLanguage.toString());
}
} // setLanguage
/**************************************************************************
* Define Language
* @param name - displayed value, e.g. English
* @param AD_Language - the code of system supported language, e.g. en_US
* (might be different than Locale - i.e. if the system does not support the language)
* @param locale - the Locale, e.g. Locale.US
* @param decimalPoint true if Decimal Point - if null, derived from Locale
* @param javaDatePattern Java date pattern as not all locales are defined - if null, derived from Locale
* @param mediaSize default media size
*/
public Language (String name, String AD_Language, Locale locale,
Boolean decimalPoint, String javaDatePattern, MediaSize mediaSize)
{
if (name == null || AD_Language == null || locale == null)
throw new IllegalArgumentException ("Language - parameter is null");
m_name = name;
m_AD_Language = AD_Language;
m_locale = locale;
//
m_decimalPoint = decimalPoint;
setDateFormat (javaDatePattern);
setMediaSize (mediaSize);
} // Language
/**
* Define Language with A4 and default decimal point and date format
* @param name - displayed value, e.g. English
* @param AD_Language - the code of system supported language, e.g. en_US
* (might be different than Locale - i.e. if the system does not support the language)
* @param locale - the Locale, e.g. Locale.US
*/
public Language (String name, String AD_Language, Locale locale)
{
this (name, AD_Language, locale, null, null, null);
} // Language
/** Name */
private String m_name;
/** Language (key) */
private String m_AD_Language;
/** Locale */
private Locale m_locale;
//
private Boolean m_decimalPoint;
private Boolean m_leftToRight;
private SimpleDateFormat m_dateFormat;
private MediaSize m_mediaSize = MediaSize.ISO.A4;
/**
* Get Language Name.
* e.g. English
* @return name
*/
public String getName()
{
return m_name;
} // getName
/**
* Get Application Dictionary Language (system supported).
* e.g. en-US
* @return AD_Language
*/
public String getAD_Language()
{
return m_AD_Language;
} // getAD_Language
/**
* Set Application Dictionary Language (system supported).
* @param AD_Language e.g. en-US
*/
public void setAD_Language (String AD_Language)
{
if (AD_Language != null)
{
m_AD_Language = AD_Language;
log.config(toString());
}
} // getAD_Language
/**
* Get Locale
* @return locale
*/
public Locale getLocale()
{
return m_locale;
} // getLocale
/**
* Overwrite Locale
* @param locale locale
*/
public void setLocale (Locale locale)
{
if (locale == null)
return;
m_locale = locale;
m_decimalPoint = null; // reset
} // getLocale
/**
* Get Language Code.
* e.g. en - derived from Locale
* @return language code
*/
public String getLanguageCode()
{
return m_locale.getLanguage();
} // getLanguageCode
/**
* Component orientation is Left To Right
* @return true if left-to-right
*/
public boolean isLeftToRight()
{
if (m_leftToRight == null)
// returns true if language not iw, ar, fa, ur
m_leftToRight = new Boolean(ComponentOrientation.getOrientation(m_locale).isLeftToRight());
return m_leftToRight.booleanValue();
} // isLeftToRight
/**
* Returns true if Decimal Point (not comma)
* @return use of decimal point
*/
public boolean isDecimalPoint()
{
if (m_decimalPoint == null)
{
DecimalFormatSymbols dfs = new DecimalFormatSymbols(m_locale);
m_decimalPoint = new Boolean(dfs.getDecimalSeparator() == '.');
}
return m_decimalPoint.booleanValue();
} // isDecimalPoint
/**
* Is This the Base Language
* @return true if base Language
*/
public boolean isBaseLanguage()
{
return this.equals(getBaseLanguage());
} // isBaseLanguage
/**
* Set Date Pattern.
* The date format is not checked for correctness
* @param javaDatePattern for details see java.text.SimpleDateFormat,
* format must be able to be converted to database date format by
* using the upper case function.
* It also must have leading zero for day and month.
*/
public void setDateFormat (String javaDatePattern)
{
if (javaDatePattern == null)
return;
m_dateFormat = (SimpleDateFormat)DateFormat.getDateInstance
(DateFormat.SHORT, m_locale);
try
{
m_dateFormat.applyPattern(javaDatePattern);
}
catch (Exception e)
{
log.severe(javaDatePattern + " - " + e);
m_dateFormat = null;
}
} // setDateFormat
/**
* Get (Short) Date Format.
* The date format must parseable by org.compiere.grid.ed.MDocDate
* i.e. leading zero for date and month
* @return date format MM/dd/yyyy - dd.MM.yyyy
*/
public SimpleDateFormat getDateFormat()
{
if (m_dateFormat == null)
{
m_dateFormat = (SimpleDateFormat)DateFormat.getDateInstance
(DateFormat.SHORT, m_locale);
String sFormat = m_dateFormat.toPattern();
// some short formats have only one M and/or d (e.g. ths US)
if (sFormat.indexOf("MM") == -1 || sFormat.indexOf("dd") == -1)
{
sFormat = sFormat.replaceFirst("d+", "dd");
sFormat = sFormat.replaceFirst("M+", "MM");
// log.finer(sFormat + " => " + nFormat);
m_dateFormat.applyPattern(sFormat);
}
// Unknown short format => use JDBC
if (m_dateFormat.toPattern().length() != 8)
m_dateFormat.applyPattern("yyyy-MM-dd");
// 4 digit year
if (m_dateFormat.toPattern().indexOf("yyyy") == -1)
{
sFormat = m_dateFormat.toPattern();
String nFormat = "";
for (int i = 0; i < sFormat.length(); i++)
{
if (sFormat.charAt(i) == 'y')
nFormat += "yy";
else
nFormat += sFormat.charAt(i);
}
m_dateFormat.applyPattern(nFormat);
}
m_dateFormat.setLenient(true);
}
return m_dateFormat;
} // getDateFormat
/**
* Get Date Time Format.
* Used for Display only
* @return Date Time format MMM d, yyyy h:mm:ss a z -or- dd.MM.yyyy HH:mm:ss z
* -or- j nnn aaaa, H' ?????? 'm' ????'
*/
public SimpleDateFormat getDateTimeFormat()
{
if(LocaleUtil.isIranLocale()){
return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
}else{
return (SimpleDateFormat)DateFormat.getDateTimeInstance
(DateFormat.MEDIUM, DateFormat.LONG, m_locale);
}
// log.finer("Pattern=" + retValue.toLocalizedPattern() + ", Loc=" + retValue.toLocalizedPattern());
} // getDateTimeFormat
/**
* Get Time Format.
* Used for Display only
* @return Time format h:mm:ss z or HH:mm:ss z
*/
public SimpleDateFormat getTimeFormat()
{
if(LocaleUtil.isIranLocale()){
return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
}else{
return (SimpleDateFormat)DateFormat.getTimeInstance
(DateFormat.LONG, m_locale);
}
} // getTimeFormat
/**
* Get Database Date Pattern.
* Derive from date pattern (make upper case)
* @return date pattern
*/
public String getDBdatePattern()
{
return getDateFormat().toPattern().toUpperCase(m_locale);
} // getDBdatePattern
/**
* Get default MediaSize
* @return media size
*/
public MediaSize getMediaSize()
{
return m_mediaSize;
} // getMediaSize
/**
* Set default MediaSize
* @param size media size
*/
public void setMediaSize (MediaSize size)
{
if (size != null)
m_mediaSize = size;
} // setMediaSize
/**
* String Representation
* @return string representation
*/
public String toString()
{
StringBuffer sb = new StringBuffer("Language=[");
sb.append(m_name).append(",Locale=").append(m_locale.toString())
.append(",AD_Language=").append(m_AD_Language)
.append(",DatePattern=").append(getDBdatePattern())
.append(",DecimalPoint=").append(isDecimalPoint())
.append("]");
return sb.toString();
} // toString
/**
* Hash Code
* @return hashcode
*/
public int hashCode()
{
return m_AD_Language.hashCode();
} // hashcode
/**
* Equals.
* Two languages are equal, if they have the same AD_Language
* @param obj compare
* @return true if AD_Language is the same
*/
public boolean equals(Object obj)
{
if (obj instanceof Language)
{
Language cmp = (Language)obj;
if (cmp.getAD_Language().equals(m_AD_Language))
return true;
}
return false;
} // equals
/**************************************************************************
* Test
* @param args ignored
*/
public static void main(String[] args)
{
System.out.println(Locale.TRADITIONAL_CHINESE);
System.out.println(Locale.TAIWAN);
System.out.println(Locale.SIMPLIFIED_CHINESE);
System.out.println(Locale.CHINESE);
System.out.println(Locale.PRC);
}
} // Language