locale.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. // Copyright 2006 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Functions for dealing with Date formatting & Parsing,
  16. * County and language name, TimeZone list.
  17. * @suppress {deprecated} Use goog.i18n instead.
  18. */
  19. /**
  20. * Namespace for locale related functions.
  21. */
  22. goog.provide('goog.locale');
  23. goog.require('goog.locale.nativeNameConstants');
  24. /**
  25. * Set current locale to the specified one.
  26. * @param {string} localeName Locale name string. We are following the usage
  27. * in CLDR, but can make a few compromise for existing name compatibility.
  28. */
  29. goog.locale.setLocale = function(localeName) {
  30. // it is common to see people use '-' as locale part separator, normalize it.
  31. localeName = localeName.replace(/-/g, '_');
  32. goog.locale.activeLocale_ = localeName;
  33. };
  34. /**
  35. * Retrieve the current locale
  36. * @return {string} Current locale name string.
  37. * @deprecated Use goog.LOCALE and goog.i18n instead.
  38. */
  39. goog.locale.getLocale = function() {
  40. if (!goog.locale.activeLocale_) {
  41. goog.locale.activeLocale_ = 'en';
  42. }
  43. return goog.locale.activeLocale_;
  44. };
  45. // Couple of constants to represent predefined Date/Time format type.
  46. /**
  47. * Enum of resources that can be registered.
  48. * @enum {string}
  49. */
  50. goog.locale.Resource = {
  51. DATE_TIME_CONSTANTS: 'DateTimeConstants',
  52. NUMBER_FORMAT_CONSTANTS: 'NumberFormatConstants',
  53. TIME_ZONE_CONSTANTS: 'TimeZoneConstants',
  54. LOCAL_NAME_CONSTANTS: 'LocaleNameConstants',
  55. TIME_ZONE_SELECTED_IDS: 'TimeZoneSelectedIds',
  56. TIME_ZONE_SELECTED_SHORT_NAMES: 'TimeZoneSelectedShortNames',
  57. TIME_ZONE_SELECTED_LONG_NAMES: 'TimeZoneSelectedLongNames',
  58. TIME_ZONE_ALL_LONG_NAMES: 'TimeZoneAllLongNames'
  59. };
  60. // BCP 47 language code:
  61. //
  62. // LanguageCode := LanguageSubtag
  63. // ("-" ScriptSubtag)?
  64. // ("-" RegionSubtag)?
  65. // ("-" VariantSubtag)?
  66. // ("@" Keyword "=" Value ("," Keyword "=" Value)* )?
  67. //
  68. // e.g. en-Latn-GB
  69. //
  70. // NOTICE:
  71. // No special format checking is performed. If you pass a none valid
  72. // language code as parameter to the following functions,
  73. // you might get an unexpected result.
  74. /**
  75. * Returns the language-subtag of the given language code.
  76. *
  77. * @param {string} languageCode Language code to extract language subtag from.
  78. * @return {string} Language subtag (in lowercase).
  79. */
  80. goog.locale.getLanguageSubTag = function(languageCode) {
  81. var result = languageCode.match(/^\w{2,3}([-_]|$)/);
  82. return result ? result[0].replace(/[_-]/g, '') : '';
  83. };
  84. /**
  85. * Returns the region-sub-tag of the given language code.
  86. *
  87. * @param {string} languageCode Language code to extract region subtag from.
  88. * @return {string} Region sub-tag (in uppercase).
  89. */
  90. goog.locale.getRegionSubTag = function(languageCode) {
  91. var result = languageCode.match(/[-_]([a-zA-Z]{2}|\d{3})([-_]|$)/);
  92. return result ? result[0].replace(/[_-]/g, '') : '';
  93. };
  94. /**
  95. * Returns the script subtag of the locale with the first alphabet in uppercase
  96. * and the rest 3 characters in lower case.
  97. *
  98. * @param {string} languageCode Language Code to extract script subtag from.
  99. * @return {string} Script subtag.
  100. */
  101. goog.locale.getScriptSubTag = function(languageCode) {
  102. var result = languageCode.split(/[-_]/g);
  103. return result.length > 1 && result[1].match(/^[a-zA-Z]{4}$/) ? result[1] : '';
  104. };
  105. /**
  106. * Returns the variant-sub-tag of the given language code.
  107. *
  108. * @param {string} languageCode Language code to extract variant subtag from.
  109. * @return {string} Variant sub-tag.
  110. */
  111. goog.locale.getVariantSubTag = function(languageCode) {
  112. var result = languageCode.match(/[-_]([a-z]{2,})/);
  113. return result ? result[1] : '';
  114. };
  115. /**
  116. * Returns the country name of the provided language code in its native
  117. * language.
  118. *
  119. * This method depends on goog.locale.nativeNameConstants available from
  120. * nativenameconstants.js. User of this method has to add dependency to this.
  121. *
  122. * @param {string} countryCode Code to lookup the country name for.
  123. *
  124. * @return {string} Country name for the provided language code.
  125. */
  126. goog.locale.getNativeCountryName = function(countryCode) {
  127. var key = goog.locale.getLanguageSubTag(countryCode) + '_' +
  128. goog.locale.getRegionSubTag(countryCode);
  129. return key in goog.locale.nativeNameConstants['COUNTRY'] ?
  130. goog.locale.nativeNameConstants['COUNTRY'][key] :
  131. countryCode;
  132. };
  133. /**
  134. * Returns the localized country name for the provided language code in the
  135. * current or provided locale symbols set.
  136. *
  137. * This method depends on `goog.locale.LocaleNameConstants__<locale>` available
  138. * from http://go/js_locale_data. User of this method has to add dependency to
  139. * this.
  140. *
  141. * @param {string} languageCode Language code to lookup the country name for.
  142. * @param {Object=} opt_localeSymbols If omitted the current locale symbol
  143. * set is used.
  144. *
  145. * @return {string} Localized country name.
  146. */
  147. goog.locale.getLocalizedCountryName = function(
  148. languageCode, opt_localeSymbols) {
  149. var code = goog.locale.getRegionSubTag(languageCode);
  150. var name =
  151. goog.locale.getLocalizedRegionNameFromRegionCode(code, opt_localeSymbols);
  152. return name == code ? languageCode : name;
  153. };
  154. /**
  155. * Returns the localized country name for the provided language code in the
  156. * current or provided locale symbols set.
  157. *
  158. * This method depends on `goog.locale.LocaleNameConstants__<locale>` available
  159. * from http://go/js_locale_data. User of this method has to add dependency to
  160. * this.
  161. *
  162. * @param {string} regionCode Two character country code or three digit region
  163. * code to look up the country name for.
  164. * @param {?Object=} opt_localeSymbols If omitted the current locale symbol
  165. * set is used.
  166. *
  167. * @return {string} Localized region name.
  168. */
  169. goog.locale.getLocalizedRegionNameFromRegionCode = function(
  170. regionCode, opt_localeSymbols) {
  171. if (!opt_localeSymbols) {
  172. opt_localeSymbols =
  173. goog.locale.getResource('LocaleNameConstants', goog.locale.getLocale());
  174. }
  175. return regionCode in opt_localeSymbols['COUNTRY'] ?
  176. opt_localeSymbols['COUNTRY'][regionCode] :
  177. regionCode;
  178. };
  179. /**
  180. * Returns the language name of the provided language code in its native
  181. * language.
  182. *
  183. * This method depends on goog.locale.nativeNameConstants available from
  184. * nativenameconstants.js. User of this method has to add dependency to this.
  185. *
  186. * @param {string} languageCode Language code to lookup the language name for.
  187. *
  188. * @return {string} Language name for the provided language code.
  189. */
  190. goog.locale.getNativeLanguageName = function(languageCode) {
  191. if (languageCode in goog.locale.nativeNameConstants['LANGUAGE'])
  192. return goog.locale.nativeNameConstants['LANGUAGE'][languageCode];
  193. var code = goog.locale.getLanguageSubTag(languageCode);
  194. return code in goog.locale.nativeNameConstants['LANGUAGE'] ?
  195. goog.locale.nativeNameConstants['LANGUAGE'][code] :
  196. languageCode;
  197. };
  198. /**
  199. * Returns the localized language name for the provided language code in
  200. * the current or provided locale symbols set.
  201. *
  202. * This method depends on `goog.locale.LocaleNameConstants__<locale>` available
  203. * from http://go/js_locale_data. User of this method has to add dependency to
  204. * this.
  205. *
  206. * @param {string} languageCode Language code to lookup the language name for.
  207. * @param {Object=} opt_localeSymbols locale symbol set if given.
  208. *
  209. * @return {string} Localized language name of the provided language code.
  210. */
  211. goog.locale.getLocalizedLanguageName = function(
  212. languageCode, opt_localeSymbols) {
  213. if (!opt_localeSymbols) {
  214. opt_localeSymbols =
  215. goog.locale.getResource('LocaleNameConstants', goog.locale.getLocale());
  216. }
  217. if (languageCode in opt_localeSymbols['LANGUAGE'])
  218. return opt_localeSymbols['LANGUAGE'][languageCode];
  219. var code = goog.locale.getLanguageSubTag(languageCode);
  220. return code in opt_localeSymbols['LANGUAGE'] ?
  221. opt_localeSymbols['LANGUAGE'][code] :
  222. languageCode;
  223. };
  224. /**
  225. * Register a resource object for certain locale.
  226. * @param {Object} dataObj The resource object being registered.
  227. * @param {goog.locale.Resource|string} resourceName String that represents
  228. * the type of resource.
  229. * @param {string} localeName Locale ID.
  230. */
  231. goog.locale.registerResource = function(dataObj, resourceName, localeName) {
  232. if (!goog.locale.resourceRegistry_[resourceName]) {
  233. goog.locale.resourceRegistry_[resourceName] = {};
  234. }
  235. goog.locale.resourceRegistry_[resourceName][localeName] = dataObj;
  236. // the first registered locale becomes active one. Usually there will be
  237. // only one locale per js binary bundle.
  238. if (!goog.locale.activeLocale_) {
  239. goog.locale.activeLocale_ = localeName;
  240. }
  241. };
  242. /**
  243. * Returns true if the required resource has already been registered.
  244. * @param {goog.locale.Resource|string} resourceName String that represents
  245. * the type of resource.
  246. * @param {string} localeName Locale ID.
  247. * @return {boolean} Whether the required resource has already been registered.
  248. */
  249. goog.locale.isResourceRegistered = function(resourceName, localeName) {
  250. return resourceName in goog.locale.resourceRegistry_ &&
  251. localeName in goog.locale.resourceRegistry_[resourceName];
  252. };
  253. /**
  254. * This object maps (resourceName, localeName) to a resourceObj.
  255. * @type {Object}
  256. * @private
  257. */
  258. goog.locale.resourceRegistry_ = {};
  259. /**
  260. * Registers the timezone constants object for a given locale name.
  261. * @param {Object} dataObj The resource object.
  262. * @param {string} localeName Locale ID.
  263. * @deprecated Use goog.i18n.TimeZone, no longer need this.
  264. */
  265. goog.locale.registerTimeZoneConstants = function(dataObj, localeName) {
  266. goog.locale.registerResource(
  267. dataObj, goog.locale.Resource.TIME_ZONE_CONSTANTS, localeName);
  268. };
  269. /**
  270. * Registers the LocaleNameConstants constants object for a given locale name.
  271. * @param {Object} dataObj The resource object.
  272. * @param {string} localeName Locale ID.
  273. */
  274. goog.locale.registerLocaleNameConstants = function(dataObj, localeName) {
  275. goog.locale.registerResource(
  276. dataObj, goog.locale.Resource.LOCAL_NAME_CONSTANTS, localeName);
  277. };
  278. /**
  279. * Registers the TimeZoneSelectedIds constants object for a given locale name.
  280. * @param {Object} dataObj The resource object.
  281. * @param {string} localeName Locale ID.
  282. */
  283. goog.locale.registerTimeZoneSelectedIds = function(dataObj, localeName) {
  284. goog.locale.registerResource(
  285. dataObj, goog.locale.Resource.TIME_ZONE_SELECTED_IDS, localeName);
  286. };
  287. /**
  288. * Registers the TimeZoneSelectedShortNames constants object for a given
  289. * locale name.
  290. * @param {Object} dataObj The resource object.
  291. * @param {string} localeName Locale ID.
  292. */
  293. goog.locale.registerTimeZoneSelectedShortNames = function(dataObj, localeName) {
  294. goog.locale.registerResource(
  295. dataObj, goog.locale.Resource.TIME_ZONE_SELECTED_SHORT_NAMES, localeName);
  296. };
  297. /**
  298. * Registers the TimeZoneSelectedLongNames constants object for a given locale
  299. * name.
  300. * @param {Object} dataObj The resource object.
  301. * @param {string} localeName Locale ID.
  302. */
  303. goog.locale.registerTimeZoneSelectedLongNames = function(dataObj, localeName) {
  304. goog.locale.registerResource(
  305. dataObj, goog.locale.Resource.TIME_ZONE_SELECTED_LONG_NAMES, localeName);
  306. };
  307. /**
  308. * Registers the TimeZoneAllLongNames constants object for a given locale name.
  309. * @param {Object} dataObj The resource object.
  310. * @param {string} localeName Locale ID.
  311. */
  312. goog.locale.registerTimeZoneAllLongNames = function(dataObj, localeName) {
  313. goog.locale.registerResource(
  314. dataObj, goog.locale.Resource.TIME_ZONE_ALL_LONG_NAMES, localeName);
  315. };
  316. /**
  317. * Retrieve specified resource for certain locale.
  318. * @param {string} resourceName String that represents the type of resource.
  319. * @param {string=} opt_locale Locale ID, if not given, current locale
  320. * will be assumed.
  321. * @return {Object|undefined} The resource object that hold all the resource
  322. * data, or undefined if not available.
  323. */
  324. goog.locale.getResource = function(resourceName, opt_locale) {
  325. var locale = opt_locale ? opt_locale : goog.locale.getLocale();
  326. if (!(resourceName in goog.locale.resourceRegistry_)) {
  327. return undefined;
  328. }
  329. return goog.locale.resourceRegistry_[resourceName][locale];
  330. };
  331. /**
  332. * Retrieve specified resource for certain locale with fallback. For example,
  333. * request of 'zh_CN' will be resolved in following order: zh_CN, zh, en.
  334. * If none of the above succeeds, of if the resource as indicated by
  335. * resourceName does not exist at all, undefined will be returned.
  336. *
  337. * @param {string} resourceName String that represents the type of resource.
  338. * @param {string=} opt_locale locale ID, if not given, current locale
  339. * will be assumed.
  340. * @return {Object|undefined} The resource object for desired locale.
  341. */
  342. goog.locale.getResourceWithFallback = function(resourceName, opt_locale) {
  343. var locale = opt_locale ? opt_locale : goog.locale.getLocale();
  344. if (!(resourceName in goog.locale.resourceRegistry_)) {
  345. return undefined;
  346. }
  347. if (locale in goog.locale.resourceRegistry_[resourceName]) {
  348. return goog.locale.resourceRegistry_[resourceName][locale];
  349. }
  350. // if locale has multiple parts (2 atmost in reality), fallback to base part.
  351. var locale_parts = locale.split('_');
  352. if (locale_parts.length > 1 &&
  353. locale_parts[0] in goog.locale.resourceRegistry_[resourceName]) {
  354. return goog.locale.resourceRegistry_[resourceName][locale_parts[0]];
  355. }
  356. // otherwise, fallback to 'en'
  357. return goog.locale.resourceRegistry_[resourceName]['en'];
  358. };
  359. // Export global functions that are used by the date time constants files.
  360. // See http://go/js_locale_data
  361. var registerLocalNameConstants = goog.locale.registerLocaleNameConstants;
  362. var registerTimeZoneSelectedIds = goog.locale.registerTimeZoneSelectedIds;
  363. var registerTimeZoneSelectedShortNames =
  364. goog.locale.registerTimeZoneSelectedShortNames;
  365. var registerTimeZoneSelectedLongNames =
  366. goog.locale.registerTimeZoneSelectedLongNames;
  367. var registerTimeZoneAllLongNames = goog.locale.registerTimeZoneAllLongNames;