@ui5/webcomponents-localization 0.0.0-cf50976ce → 0.0.0-d479b681b

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/.eslintignore +1 -1
  2. package/.npsrc.json +3 -0
  3. package/CHANGELOG.md +205 -0
  4. package/{src/Assets-static.js → dist/Assets-static.d.ts} +0 -1
  5. package/dist/Assets-static.js +1 -0
  6. package/dist/Assets-static.js.map +1 -0
  7. package/dist/Assets.d.ts +1 -0
  8. package/dist/Assets.js +1 -0
  9. package/dist/Assets.js.map +1 -0
  10. package/dist/DateFormat.d.ts +6 -0
  11. package/dist/DateFormat.js +6 -2
  12. package/dist/DateFormat.js.map +1 -0
  13. package/dist/LocaleData.d.ts +6 -0
  14. package/dist/LocaleData.js +6 -2
  15. package/dist/LocaleData.js.map +1 -0
  16. package/dist/dates/CalendarDate.d.ts +43 -0
  17. package/dist/dates/CalendarDate.js +171 -207
  18. package/dist/dates/CalendarDate.js.map +1 -0
  19. package/dist/dates/ExtremeDates.d.ts +5 -0
  20. package/dist/dates/ExtremeDates.js +25 -35
  21. package/dist/dates/ExtremeDates.js.map +1 -0
  22. package/dist/dates/UI5Date.d.ts +6 -0
  23. package/dist/dates/UI5Date.js +7 -0
  24. package/dist/dates/UI5Date.js.map +1 -0
  25. package/dist/dates/UniversalDate.d.ts +47 -0
  26. package/dist/dates/UniversalDate.js +5 -0
  27. package/dist/dates/UniversalDate.js.map +1 -0
  28. package/dist/dates/calculateWeekNumber.d.ts +5 -0
  29. package/dist/dates/calculateWeekNumber.js +42 -48
  30. package/dist/dates/calculateWeekNumber.js.map +1 -0
  31. package/dist/dates/convertMonthNumbersToMonthNames.d.ts +16 -0
  32. package/dist/dates/convertMonthNumbersToMonthNames.js +15 -18
  33. package/dist/dates/convertMonthNumbersToMonthNames.js.map +1 -0
  34. package/dist/dates/getDaysInMonth.d.ts +3 -0
  35. package/dist/dates/getDaysInMonth.js +7 -8
  36. package/dist/dates/getDaysInMonth.js.map +1 -0
  37. package/dist/dates/getRoundedTimestamp.d.ts +7 -0
  38. package/dist/dates/getRoundedTimestamp.js +10 -9
  39. package/dist/dates/getRoundedTimestamp.js.map +1 -0
  40. package/dist/dates/getTodayUTCTimestamp.d.ts +7 -0
  41. package/dist/dates/getTodayUTCTimestamp.js +3 -3
  42. package/dist/dates/getTodayUTCTimestamp.js.map +1 -0
  43. package/dist/dates/modifyDateBy.d.ts +13 -0
  44. package/dist/dates/modifyDateBy.js +27 -29
  45. package/dist/dates/modifyDateBy.js.map +1 -0
  46. package/dist/dates/transformDateToSecondaryType.d.ts +7 -0
  47. package/dist/dates/transformDateToSecondaryType.js +13 -15
  48. package/dist/dates/transformDateToSecondaryType.js.map +1 -0
  49. package/dist/features/calendar/Buddhist.js +1 -0
  50. package/dist/features/calendar/Buddhist.js.map +1 -0
  51. package/dist/features/calendar/Gregorian.js +1 -0
  52. package/dist/features/calendar/Gregorian.js.map +1 -0
  53. package/dist/features/calendar/Islamic.js +1 -0
  54. package/dist/features/calendar/Islamic.js.map +1 -0
  55. package/dist/features/calendar/Japanese.js +1 -0
  56. package/dist/features/calendar/Japanese.js.map +1 -0
  57. package/dist/features/calendar/Persian.js +1 -0
  58. package/dist/features/calendar/Persian.js.map +1 -0
  59. package/dist/generated/assets/cldr/ar.json +2816 -5906
  60. package/dist/generated/assets/cldr/ar_EG.json +2816 -5906
  61. package/dist/generated/assets/cldr/ar_SA.json +2815 -5906
  62. package/dist/generated/assets/cldr/bg.json +2733 -4979
  63. package/dist/generated/assets/cldr/ca.json +2680 -4996
  64. package/dist/generated/assets/cldr/cs.json +2716 -5498
  65. package/dist/generated/assets/cldr/cy.json +2797 -5884
  66. package/dist/generated/assets/cldr/da.json +2597 -4888
  67. package/dist/generated/assets/cldr/de.json +2614 -4916
  68. package/dist/generated/assets/cldr/de_AT.json +2614 -4917
  69. package/dist/generated/assets/cldr/de_CH.json +2614 -4915
  70. package/dist/generated/assets/cldr/el.json +2595 -4883
  71. package/dist/generated/assets/cldr/el_CY.json +2595 -4883
  72. package/dist/generated/assets/cldr/en.json +2583 -4971
  73. package/dist/generated/assets/cldr/en_AU.json +2592 -4962
  74. package/dist/generated/assets/cldr/en_GB.json +2584 -4971
  75. package/dist/generated/assets/cldr/en_HK.json +2593 -4977
  76. package/dist/generated/assets/cldr/en_IE.json +2584 -4971
  77. package/dist/generated/assets/cldr/en_IN.json +2588 -4972
  78. package/dist/generated/assets/cldr/en_NZ.json +2584 -4971
  79. package/dist/generated/assets/cldr/en_PG.json +2584 -4972
  80. package/dist/generated/assets/cldr/en_SG.json +2588 -4973
  81. package/dist/generated/assets/cldr/en_ZA.json +2584 -4972
  82. package/dist/generated/assets/cldr/es.json +2640 -4912
  83. package/dist/generated/assets/cldr/es_AR.json +2645 -4914
  84. package/dist/generated/assets/cldr/es_BO.json +2645 -4913
  85. package/dist/generated/assets/cldr/es_CL.json +2645 -4914
  86. package/dist/generated/assets/cldr/es_CO.json +2644 -4913
  87. package/dist/generated/assets/cldr/es_MX.json +2645 -4915
  88. package/dist/generated/assets/cldr/es_PE.json +2645 -4913
  89. package/dist/generated/assets/cldr/es_UY.json +2645 -4915
  90. package/dist/generated/assets/cldr/es_VE.json +2645 -4914
  91. package/dist/generated/assets/cldr/et.json +2599 -4967
  92. package/dist/generated/assets/cldr/fa.json +2618 -4883
  93. package/dist/generated/assets/cldr/fi.json +2726 -5008
  94. package/dist/generated/assets/cldr/fr.json +2590 -4979
  95. package/dist/generated/assets/cldr/fr_BE.json +2590 -4979
  96. package/dist/generated/assets/cldr/fr_CA.json +2605 -4973
  97. package/dist/generated/assets/cldr/fr_CH.json +2607 -4997
  98. package/dist/generated/assets/cldr/fr_LU.json +2590 -4979
  99. package/dist/generated/assets/cldr/he.json +2711 -5378
  100. package/dist/generated/assets/cldr/hi.json +2602 -4829
  101. package/dist/generated/assets/cldr/hr.json +2652 -4919
  102. package/dist/generated/assets/cldr/hu.json +2598 -4856
  103. package/dist/generated/assets/cldr/id.json +2544 -4658
  104. package/dist/generated/assets/cldr/it.json +2590 -4950
  105. package/dist/generated/assets/cldr/it_CH.json +2590 -4950
  106. package/dist/generated/assets/cldr/ja.json +2663 -4830
  107. package/dist/generated/assets/cldr/kk.json +2589 -4725
  108. package/dist/generated/assets/cldr/ko.json +2641 -4738
  109. package/dist/generated/assets/cldr/lt.json +2720 -5481
  110. package/dist/generated/assets/cldr/lv.json +2644 -5112
  111. package/dist/generated/assets/cldr/ms.json +2538 -4515
  112. package/dist/generated/assets/cldr/nb.json +2621 -4977
  113. package/dist/generated/assets/cldr/nl.json +2601 -4884
  114. package/dist/generated/assets/cldr/nl_BE.json +2601 -4884
  115. package/dist/generated/assets/cldr/pl.json +2723 -5176
  116. package/dist/generated/assets/cldr/pt.json +2607 -4805
  117. package/dist/generated/assets/cldr/pt_PT.json +2658 -4940
  118. package/dist/generated/assets/cldr/ro.json +2645 -5090
  119. package/dist/generated/assets/cldr/ru.json +2704 -5407
  120. package/dist/generated/assets/cldr/ru_UA.json +2704 -5407
  121. package/dist/generated/assets/cldr/sk.json +2726 -5370
  122. package/dist/generated/assets/cldr/sl.json +2688 -5340
  123. package/dist/generated/assets/cldr/sr.json +2663 -5126
  124. package/dist/generated/assets/cldr/sr_Latn.json +2666 -5127
  125. package/dist/generated/assets/cldr/sv.json +2631 -5011
  126. package/dist/generated/assets/cldr/th.json +2635 -4797
  127. package/dist/generated/assets/cldr/tr.json +2612 -4979
  128. package/dist/generated/assets/cldr/uk.json +2684 -5353
  129. package/dist/generated/assets/cldr/vi.json +2555 -4673
  130. package/dist/generated/assets/cldr/zh_CN.json +2555 -4632
  131. package/dist/generated/assets/cldr/zh_HK.json +2563 -4640
  132. package/dist/generated/assets/cldr/zh_SG.json +2562 -4640
  133. package/dist/generated/assets/cldr/zh_TW.json +2587 -4728
  134. package/dist/getCachedLocaleDataInstance.d.ts +4 -0
  135. package/dist/getCachedLocaleDataInstance.js +6 -9
  136. package/dist/getCachedLocaleDataInstance.js.map +1 -0
  137. package/dist/locale/getLocaleData.d.ts +11 -0
  138. package/dist/locale/getLocaleData.js +12 -16
  139. package/dist/locale/getLocaleData.js.map +1 -0
  140. package/dist/sap/base/Log.js +28 -29
  141. package/dist/sap/base/assert.js +5 -6
  142. package/dist/sap/base/util/LoaderExtensions.d.ts +4 -0
  143. package/dist/sap/base/util/LoaderExtensions.js +9 -12
  144. package/dist/sap/base/util/LoaderExtensions.js.map +1 -0
  145. package/dist/sap/ui/core/Configuration.d.ts +17 -0
  146. package/dist/sap/ui/core/Configuration.js +21 -0
  147. package/dist/sap/ui/core/Configuration.js.map +1 -0
  148. package/dist/sap/ui/core/Core.d.ts +26 -0
  149. package/dist/sap/ui/core/Core.js +7 -34
  150. package/dist/sap/ui/core/Core.js.map +1 -0
  151. package/dist/sap/ui/core/FormatSettings.d.ts +10 -0
  152. package/dist/sap/ui/core/FormatSettings.js +14 -0
  153. package/dist/sap/ui/core/FormatSettings.js.map +1 -0
  154. package/dist/sap/ui/core/Locale.js +3 -0
  155. package/dist/sap/ui/core/LocaleData.js +151 -22
  156. package/dist/sap/ui/core/date/Buddhist.js +0 -6
  157. package/dist/sap/ui/core/date/CalendarUtils.js +36 -0
  158. package/dist/sap/ui/core/date/CalendarWeekNumbering.js +7 -0
  159. package/dist/sap/ui/core/date/Islamic.js +3 -3
  160. package/dist/sap/ui/core/date/Japanese.js +4 -4
  161. package/dist/sap/ui/core/date/UI5Date.js +305 -0
  162. package/dist/sap/ui/core/date/UniversalDate.js +79 -27
  163. package/dist/sap/ui/core/format/DateFormat.js +463 -349
  164. package/dist/sap/ui/core/format/TimezoneUtil.js +19 -13
  165. package/{package-scripts.js → package-scripts.cjs} +7 -5
  166. package/package.json +7 -5
  167. package/tsconfig.json +14 -0
  168. package/used-modules.txt +4 -1
  169. package/src/Assets.js +0 -2
  170. package/src/DateFormat.js +0 -3
  171. package/src/LocaleData.js +0 -3
  172. package/src/dates/CalendarDate.js +0 -229
  173. package/src/dates/ExtremeDates.js +0 -39
  174. package/src/dates/calculateWeekNumber.js +0 -51
  175. package/src/dates/convertMonthNumbersToMonthNames.js +0 -33
  176. package/src/dates/getDaysInMonth.js +0 -11
  177. package/src/dates/getRoundedTimestamp.js +0 -14
  178. package/src/dates/getTodayUTCTimestamp.js +0 -9
  179. package/src/dates/modifyDateBy.js +0 -42
  180. package/src/dates/transformDateToSecondaryType.js +0 -20
  181. package/src/getCachedLocaleDataInstance.js +0 -13
  182. package/src/locale/getLocaleData.js +0 -27
  183. package/src/sap/base/util/LoaderExtensions.js +0 -17
  184. package/src/sap/ui/core/Core.js +0 -40
  185. /package/{config/.eslintrc.js → .eslintrc.cjs} +0 -0
  186. /package/{src/features/calendar/Buddhist.js → dist/features/calendar/Buddhist.d.ts} +0 -0
  187. /package/{src/features/calendar/Gregorian.js → dist/features/calendar/Gregorian.d.ts} +0 -0
  188. /package/{src/features/calendar/Islamic.js → dist/features/calendar/Islamic.d.ts} +0 -0
  189. /package/{src/features/calendar/Japanese.js → dist/features/calendar/Japanese.d.ts} +0 -0
  190. /package/{src/features/calendar/Persian.js → dist/features/calendar/Persian.d.ts} +0 -0
@@ -1,13 +1,16 @@
1
- import Core from '../Core.js';
2
1
  import CalendarType from '../CalendarType.js';
3
2
  import Locale from '../Locale.js';
4
3
  import LocaleData from '../LocaleData.js';
4
+ import UI5Date from '../date/UI5Date.js';
5
5
  import UniversalDate from '../date/UniversalDate.js';
6
+ import CalendarUtils from '../date/CalendarUtils.js';
7
+ import CalendarWeekNumbering from '../date/CalendarWeekNumbering.js';
6
8
  import TimezoneUtil from './TimezoneUtil.js';
7
9
  import deepEqual from '../../../base/util/deepEqual.js';
8
10
  import formatMessage from '../../../base/strings/formatMessage.js';
9
11
  import Log from '../../../base/Log.js';
10
12
  import extend from '../../../base/util/extend.js';
13
+ import Configuration from '../Configuration.js';
11
14
  var DateFormat = function () {
12
15
  throw new Error();
13
16
  };
@@ -256,14 +259,15 @@ function createIntervalPatternWithNormalConnector(oFormat) {
256
259
  sPattern = sPattern.replace(/[^\{\}01 ]/, '-');
257
260
  return sPattern.replace(/\{(0|1)\}/g, oFormat.oFormatOptions.pattern);
258
261
  }
259
- DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
260
- var oFormat = Object.create(this.prototype);
262
+ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo, bIsFallback) {
263
+ var aFallbackFormatOptions, oFormat, sPattern;
264
+ oFormat = Object.create(this.prototype);
261
265
  if (oFormatOptions instanceof Locale) {
262
266
  oLocale = oFormatOptions;
263
267
  oFormatOptions = undefined;
264
268
  }
265
269
  if (!oLocale) {
266
- oLocale = Core.getConfiguration().getFormatSettings().getFormatLocale();
270
+ oLocale = Configuration.getFormatSettings().getFormatLocale();
267
271
  }
268
272
  oFormat.oLocale = oLocale;
269
273
  oFormat.oLocaleData = LocaleData.getInstance(oLocale);
@@ -279,7 +283,13 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
279
283
  }
280
284
  oFormat.type = oInfo.type;
281
285
  if (!oFormat.oFormatOptions.calendarType) {
282
- oFormat.oFormatOptions.calendarType = Core.getConfiguration().getCalendarType();
286
+ oFormat.oFormatOptions.calendarType = Configuration.getCalendarType();
287
+ }
288
+ if (oFormat.oFormatOptions.firstDayOfWeek === undefined && oFormat.oFormatOptions.minimalDaysInFirstWeek !== undefined || oFormat.oFormatOptions.firstDayOfWeek !== undefined && oFormat.oFormatOptions.minimalDaysInFirstWeek === undefined) {
289
+ throw new TypeError('Format options firstDayOfWeek and minimalDaysInFirstWeek need both to be set, but only one was provided.');
290
+ }
291
+ if (oFormat.oFormatOptions.calendarWeekNumbering && !Object.values(CalendarWeekNumbering).includes(oFormat.oFormatOptions.calendarWeekNumbering)) {
292
+ throw new TypeError('Illegal format option calendarWeekNumbering: \'' + oFormat.oFormatOptions.calendarWeekNumbering + '\'');
283
293
  }
284
294
  if (!oFormat.oFormatOptions.pattern) {
285
295
  if (oFormat.oFormatOptions.format) {
@@ -304,30 +314,27 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
304
314
  var sCommonConnectorPattern = createIntervalPatternWithNormalConnector(oFormat);
305
315
  oFormat.intervalPatterns.push(sCommonConnectorPattern);
306
316
  }
307
- if (!oFormat.oFormatOptions.fallback) {
308
- if (!oInfo.oFallbackFormats) {
309
- oInfo.oFallbackFormats = {};
317
+ if (!bIsFallback) {
318
+ aFallbackFormatOptions = oInfo.aFallbackFormatOptions;
319
+ if (oInfo.bShortFallbackFormatOptions) {
320
+ sPattern = oInfo.getPattern(oFormat.oLocaleData, 'short');
321
+ aFallbackFormatOptions = aFallbackFormatOptions.concat(DateFormat._createFallbackOptionsWithoutDelimiter(sPattern));
310
322
  }
311
- var sLocale = oLocale.toString(), sCalendarType = oFormat.oFormatOptions.calendarType, sKey = sLocale + '-' + sCalendarType, sPattern, aFallbackFormatOptions;
312
323
  if (oFormat.oFormatOptions.pattern && oInfo.bPatternFallbackWithoutDelimiter) {
313
- sKey = sKey + '-' + oFormat.oFormatOptions.pattern;
314
- }
315
- if (oFormat.oFormatOptions.interval) {
316
- sKey = sKey + '-' + 'interval';
317
- }
318
- var oFallbackFormats = oInfo.oFallbackFormats[sKey] ? Object.assign({}, oInfo.oFallbackFormats[sKey]) : undefined;
319
- if (!oFallbackFormats) {
320
- aFallbackFormatOptions = oInfo.aFallbackFormatOptions;
321
- if (oInfo.bShortFallbackFormatOptions) {
322
- sPattern = oInfo.getPattern(oFormat.oLocaleData, 'short');
323
- aFallbackFormatOptions = aFallbackFormatOptions.concat(DateFormat._createFallbackOptionsWithoutDelimiter(sPattern));
324
- }
325
- if (oFormat.oFormatOptions.pattern && oInfo.bPatternFallbackWithoutDelimiter) {
326
- aFallbackFormatOptions = DateFormat._createFallbackOptionsWithoutDelimiter(oFormat.oFormatOptions.pattern).concat(aFallbackFormatOptions);
327
- }
328
- oFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, sCalendarType, oLocale, oInfo, oFormat.oFormatOptions);
329
- }
330
- oFormat.aFallbackFormats = oFallbackFormats;
324
+ aFallbackFormatOptions = DateFormat._createFallbackOptionsWithoutDelimiter(oFormat.oFormatOptions.pattern).concat(aFallbackFormatOptions);
325
+ }
326
+ aFallbackFormatOptions = aFallbackFormatOptions.reduce(function (aFallbacks, oOptions) {
327
+ var aKeys = Object.keys(oOptions), bDuplicate = aFallbacks.some(function (oOptions0) {
328
+ return Object.keys(oOptions0).length === aKeys.length && aKeys.every(function (sKey) {
329
+ return oOptions0[sKey] === oOptions[sKey];
330
+ });
331
+ });
332
+ if (!bDuplicate) {
333
+ aFallbacks.push(oOptions);
334
+ }
335
+ return aFallbacks;
336
+ }, []);
337
+ oFormat.aFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, oFormat.oFormatOptions.calendarType, oLocale, oInfo, oFormat.oFormatOptions);
331
338
  }
332
339
  oFormat.oRequiredParts = oInfo.oRequiredParts;
333
340
  oFormat.aRelativeScales = oInfo.aRelativeScales;
@@ -361,7 +368,15 @@ DateFormat.prototype.init = function () {
361
368
  this.aErasNarrow = this.oLocaleData.getEras('narrow', sCalendarType);
362
369
  this.aErasAbbrev = this.oLocaleData.getEras('abbreviated', sCalendarType);
363
370
  this.aErasWide = this.oLocaleData.getEras('wide', sCalendarType);
364
- this.aDayPeriods = this.oLocaleData.getDayPeriods('abbreviated', sCalendarType);
371
+ this.aDayPeriodsAbbrev = this.oLocaleData.getDayPeriods('abbreviated', sCalendarType);
372
+ this.aDayPeriodsNarrow = this.oLocaleData.getDayPeriods('narrow', sCalendarType);
373
+ this.aDayPeriodsWide = this.oLocaleData.getDayPeriods('wide', sCalendarType);
374
+ this.oFlexibleDayPeriodsAbbrev = this.oLocaleData.getFlexibleDayPeriods('abbreviated', sCalendarType);
375
+ this.oFlexibleDayPeriodsNarrow = this.oLocaleData.getFlexibleDayPeriods('narrow', sCalendarType);
376
+ this.oFlexibleDayPeriodsWide = this.oLocaleData.getFlexibleDayPeriods('wide', sCalendarType);
377
+ this.oFlexibleDayPeriodsAbbrevSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('abbreviated', sCalendarType);
378
+ this.oFlexibleDayPeriodsNarrowSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('narrow', sCalendarType);
379
+ this.oFlexibleDayPeriodsWideSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('wide', sCalendarType);
365
380
  this.aFormatArray = this.parseCldrDatePattern(this.oFormatOptions.pattern);
366
381
  this.sAllowedCharacters = this.getAllowedCharacters(this.aFormatArray);
367
382
  };
@@ -378,10 +393,7 @@ DateFormat._createFallbackFormat = function (aFallbackFormatOptions, sCalendarTy
378
393
  oFormatOptions.interval = true;
379
394
  }
380
395
  oFormatOptions.calendarType = sCalendarType;
381
- oFormatOptions.fallback = true;
382
- var oFallbackFormat = DateFormat.createInstance(oFormatOptions, oLocale, oInfo);
383
- oFallbackFormat.bIsFallback = true;
384
- return oFallbackFormat;
396
+ return DateFormat.createInstance(oFormatOptions, oLocale, oInfo, true);
385
397
  });
386
398
  };
387
399
  DateFormat._createFallbackOptionsWithoutDelimiter = function (sBasePattern) {
@@ -417,9 +429,6 @@ var oParseHelper = {
417
429
  while (iLength < iMaxLength && this.isNumber(sValue.charCodeAt(iLength))) {
418
430
  iLength++;
419
431
  }
420
- if (typeof sValue !== 'string') {
421
- sValue = sValue.toString();
422
- }
423
432
  return sValue.substr(0, iLength);
424
433
  },
425
434
  startsWithIgnoreCase: function (sValue, sSubstring, sLocale) {
@@ -452,7 +461,7 @@ var oParseHelper = {
452
461
  },
453
462
  parseTZ: function (sValue, bColonSeparated) {
454
463
  var iLength = 0;
455
- var iTZFactor = sValue.charAt(0) == '+' ? -1 : 1;
464
+ var iTZFactor = sValue.charAt(0) === '+' ? -1 : 1;
456
465
  var sPart;
457
466
  iLength++;
458
467
  sPart = this.findNumbers(sValue.substr(iLength), 2);
@@ -472,14 +481,30 @@ var oParseHelper = {
472
481
  tzDiff: (iTZDiff + 60 * iTZDiffHour) * 60 * iTZFactor
473
482
  };
474
483
  },
475
- checkValid: function (sType, bPartInvalid, oFormat) {
476
- if (sType in oFormat.oRequiredParts && bPartInvalid) {
484
+ checkValid: function (sSymbolName, bPartInvalid, oFormat) {
485
+ if (sSymbolName in oFormat.oRequiredParts && bPartInvalid) {
477
486
  return false;
478
487
  }
488
+ return true;
479
489
  }
480
490
  };
491
+ DateFormat._createPatternSymbol = function (mParameters) {
492
+ var fnIsNumeric = typeof mParameters.isNumeric === 'function' && mParameters.isNumeric || function () {
493
+ return mParameters.isNumeric || false;
494
+ };
495
+ return {
496
+ name: mParameters.name,
497
+ format: mParameters.format || function () {
498
+ return '';
499
+ },
500
+ parse: mParameters.parse || function () {
501
+ return {};
502
+ },
503
+ isNumeric: fnIsNumeric
504
+ };
505
+ };
481
506
  DateFormat.prototype.oSymbols = {
482
- '': {
507
+ '': DateFormat._createPatternSymbol({
483
508
  name: 'text',
484
509
  format: function (oField, oDate) {
485
510
  return oField.value;
@@ -521,8 +546,8 @@ DateFormat.prototype.oSymbols = {
521
546
  return { valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat) };
522
547
  }
523
548
  }
524
- },
525
- 'G': {
549
+ }),
550
+ 'G': DateFormat._createPatternSymbol({
526
551
  name: 'era',
527
552
  format: function (oField, oDate, bUTC, oFormat) {
528
553
  var iEra = oDate.getUTCEra();
@@ -555,34 +580,35 @@ DateFormat.prototype.oSymbols = {
555
580
  valid: oParseHelper.checkValid(oPart.type, true, oFormat)
556
581
  };
557
582
  }
558
- },
559
- 'y': {
583
+ }),
584
+ 'y': DateFormat._createPatternSymbol({
560
585
  name: 'year',
561
586
  format: function (oField, oDate, bUTC, oFormat) {
562
587
  var iYear = oDate.getUTCFullYear();
563
588
  var sYear = String(iYear);
564
589
  var sCalendarType = oFormat.oFormatOptions.calendarType;
565
- if (oField.digits == 2 && sYear.length > 2) {
590
+ if (oField.digits === 2 && sYear.length > 2) {
566
591
  sYear = sYear.substr(sYear.length - 2);
567
592
  }
568
- if (sCalendarType != CalendarType.Japanese && oField.digits == 1 && iYear < 100) {
593
+ if (sCalendarType !== CalendarType.Japanese && oField.digits === 1 && iYear < 100) {
569
594
  sYear = sYear.padStart(4, '0');
570
595
  }
571
596
  return sYear.padStart(oField.digits, '0');
572
597
  },
573
598
  parse: function (sValue, oPart, oFormat, oConfig) {
574
- var sCalendarType = oFormat.oFormatOptions.calendarType;
575
- var sPart;
576
- if (oPart.digits == 1) {
577
- sPart = oParseHelper.findNumbers(sValue, 4);
578
- } else if (oPart.digits == 2) {
579
- sPart = oParseHelper.findNumbers(sValue, 2);
599
+ var iExpectedDigits, sPart, bPartInvalid, sCalendarType = oFormat.oFormatOptions.calendarType;
600
+ if (oPart.digits === 1) {
601
+ iExpectedDigits = 4;
602
+ } else if (oPart.digits === 2) {
603
+ iExpectedDigits = 2;
580
604
  } else {
581
- sPart = oParseHelper.findNumbers(sValue, oPart.digits);
605
+ iExpectedDigits = oPart.digits;
582
606
  }
607
+ sPart = oParseHelper.findNumbers(sValue, iExpectedDigits);
608
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length !== iExpectedDigits;
583
609
  var iYear = parseInt(sPart);
584
- if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
585
- var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iYear - iCurrentYear;
610
+ if (sCalendarType !== CalendarType.Japanese && sPart.length <= 2) {
611
+ var oCurrentDate = UniversalDate.getInstance(UI5Date.getInstance(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iYear - iCurrentYear;
586
612
  if (iYearDiff < -70) {
587
613
  iYear += (iCurrentCentury + 1) * 100;
588
614
  } else if (iYearDiff < 30) {
@@ -593,40 +619,42 @@ DateFormat.prototype.oSymbols = {
593
619
  }
594
620
  return {
595
621
  length: sPart.length,
596
- valid: oParseHelper.checkValid(oPart.type, sPart === '', oFormat),
622
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat),
597
623
  year: iYear
598
624
  };
599
- }
600
- },
601
- 'Y': {
625
+ },
626
+ isNumeric: true
627
+ }),
628
+ 'Y': DateFormat._createPatternSymbol({
602
629
  name: 'weekYear',
603
630
  format: function (oField, oDate, bUTC, oFormat) {
604
- var oWeek = oDate.getUTCWeek();
631
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
605
632
  var iWeekYear = oWeek.year;
606
633
  var sWeekYear = String(iWeekYear);
607
634
  var sCalendarType = oFormat.oFormatOptions.calendarType;
608
- if (oField.digits == 2 && sWeekYear.length > 2) {
635
+ if (oField.digits === 2 && sWeekYear.length > 2) {
609
636
  sWeekYear = sWeekYear.substr(sWeekYear.length - 2);
610
637
  }
611
- if (sCalendarType != CalendarType.Japanese && oField.digits == 1 && iWeekYear < 100) {
638
+ if (sCalendarType !== CalendarType.Japanese && oField.digits === 1 && iWeekYear < 100) {
612
639
  sWeekYear = sWeekYear.padStart(4, '0');
613
640
  }
614
641
  return sWeekYear.padStart(oField.digits, '0');
615
642
  },
616
643
  parse: function (sValue, oPart, oFormat, oConfig) {
617
- var sCalendarType = oFormat.oFormatOptions.calendarType;
618
- var sPart;
619
- if (oPart.digits == 1) {
620
- sPart = oParseHelper.findNumbers(sValue, 4);
621
- } else if (oPart.digits == 2) {
622
- sPart = oParseHelper.findNumbers(sValue, 2);
644
+ var iExpectedDigits, sPart, bPartInvalid, sCalendarType = oFormat.oFormatOptions.calendarType;
645
+ if (oPart.digits === 1) {
646
+ iExpectedDigits = 4;
647
+ } else if (oPart.digits === 2) {
648
+ iExpectedDigits = 2;
623
649
  } else {
624
- sPart = oParseHelper.findNumbers(sValue, oPart.digits);
650
+ iExpectedDigits = oPart.digits;
625
651
  }
652
+ sPart = oParseHelper.findNumbers(sValue, iExpectedDigits);
653
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length !== iExpectedDigits;
626
654
  var iYear = parseInt(sPart);
627
655
  var iWeekYear = iYear;
628
- if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
629
- var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iWeekYear - iCurrentYear;
656
+ if (sCalendarType !== CalendarType.Japanese && sPart.length <= 2) {
657
+ var oCurrentDate = UniversalDate.getInstance(UI5Date.getInstance(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iWeekYear - iCurrentYear;
630
658
  if (iYearDiff < -70) {
631
659
  iWeekYear += (iCurrentCentury + 1) * 100;
632
660
  } else if (iYearDiff < 30) {
@@ -637,19 +665,20 @@ DateFormat.prototype.oSymbols = {
637
665
  }
638
666
  return {
639
667
  length: sPart.length,
640
- valid: oParseHelper.checkValid(oPart.type, sPart === '', oFormat),
668
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat),
641
669
  year: iYear,
642
670
  weekYear: iWeekYear
643
671
  };
644
- }
645
- },
646
- 'M': {
672
+ },
673
+ isNumeric: true
674
+ }),
675
+ 'M': DateFormat._createPatternSymbol({
647
676
  name: 'month',
648
677
  format: function (oField, oDate, bUTC, oFormat) {
649
678
  var iMonth = oDate.getUTCMonth();
650
- if (oField.digits == 3) {
679
+ if (oField.digits === 3) {
651
680
  return oFormat.aMonthsAbbrev[iMonth];
652
- } else if (oField.digits == 4) {
681
+ } else if (oField.digits === 4) {
653
682
  return oFormat.aMonthsWide[iMonth];
654
683
  } else if (oField.digits > 4) {
655
684
  return oFormat.aMonthsNarrow[iMonth];
@@ -658,20 +687,18 @@ DateFormat.prototype.oSymbols = {
658
687
  }
659
688
  },
660
689
  parse: function (sValue, oPart, oFormat, oConfig) {
661
- var aMonthsVariants = [
662
- oFormat.aMonthsWide,
663
- oFormat.aMonthsWideSt,
664
- oFormat.aMonthsAbbrev,
665
- oFormat.aMonthsAbbrevSt,
666
- oFormat.aMonthsNarrow,
667
- oFormat.aMonthsNarrowSt
668
- ];
669
- var bValid;
670
- var iMonth;
671
- var sPart;
690
+ var iMonth, sPart, bPartInvalid, bValid, aMonthsVariants = [
691
+ oFormat.aMonthsWide,
692
+ oFormat.aMonthsWideSt,
693
+ oFormat.aMonthsAbbrev,
694
+ oFormat.aMonthsAbbrevSt,
695
+ oFormat.aMonthsNarrow,
696
+ oFormat.aMonthsNarrowSt
697
+ ];
672
698
  if (oPart.digits < 3) {
673
699
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
674
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
700
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
701
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
675
702
  iMonth = parseInt(sPart) - 1;
676
703
  if (oConfig.strict && (iMonth > 11 || iMonth < 0)) {
677
704
  bValid = false;
@@ -694,15 +721,18 @@ DateFormat.prototype.oSymbols = {
694
721
  length: sPart ? sPart.length : 0,
695
722
  valid: bValid
696
723
  };
724
+ },
725
+ isNumeric: function (iDigits) {
726
+ return iDigits < 3;
697
727
  }
698
- },
699
- 'L': {
728
+ }),
729
+ 'L': DateFormat._createPatternSymbol({
700
730
  name: 'monthStandalone',
701
731
  format: function (oField, oDate, bUTC, oFormat) {
702
732
  var iMonth = oDate.getUTCMonth();
703
- if (oField.digits == 3) {
733
+ if (oField.digits === 3) {
704
734
  return oFormat.aMonthsAbbrevSt[iMonth];
705
- } else if (oField.digits == 4) {
735
+ } else if (oField.digits === 4) {
706
736
  return oFormat.aMonthsWideSt[iMonth];
707
737
  } else if (oField.digits > 4) {
708
738
  return oFormat.aMonthsNarrowSt[iMonth];
@@ -711,20 +741,18 @@ DateFormat.prototype.oSymbols = {
711
741
  }
712
742
  },
713
743
  parse: function (sValue, oPart, oFormat, oConfig) {
714
- var aMonthsVariants = [
715
- oFormat.aMonthsWide,
716
- oFormat.aMonthsWideSt,
717
- oFormat.aMonthsAbbrev,
718
- oFormat.aMonthsAbbrevSt,
719
- oFormat.aMonthsNarrow,
720
- oFormat.aMonthsNarrowSt
721
- ];
722
- var bValid;
723
- var iMonth;
724
- var sPart;
744
+ var iMonth, sPart, bPartInvalid, bValid, aMonthsVariants = [
745
+ oFormat.aMonthsWide,
746
+ oFormat.aMonthsWideSt,
747
+ oFormat.aMonthsAbbrev,
748
+ oFormat.aMonthsAbbrevSt,
749
+ oFormat.aMonthsNarrow,
750
+ oFormat.aMonthsNarrowSt
751
+ ];
725
752
  if (oPart.digits < 3) {
726
753
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
727
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
754
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
755
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
728
756
  iMonth = parseInt(sPart) - 1;
729
757
  if (oConfig.strict && (iMonth > 11 || iMonth < 0)) {
730
758
  bValid = false;
@@ -747,12 +775,15 @@ DateFormat.prototype.oSymbols = {
747
775
  length: sPart ? sPart.length : 0,
748
776
  valid: bValid
749
777
  };
778
+ },
779
+ isNumeric: function (iDigits) {
780
+ return iDigits < 3;
750
781
  }
751
- },
752
- 'w': {
782
+ }),
783
+ 'w': DateFormat._createPatternSymbol({
753
784
  name: 'weekInYear',
754
785
  format: function (oField, oDate, bUTC, oFormat) {
755
- var oWeek = oDate.getUTCWeek();
786
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
756
787
  var iWeek = oWeek.week;
757
788
  var sWeek = String(iWeek + 1);
758
789
  if (oField.digits < 3) {
@@ -763,15 +794,13 @@ DateFormat.prototype.oSymbols = {
763
794
  return sWeek;
764
795
  },
765
796
  parse: function (sValue, oPart, oFormat, oConfig) {
766
- var bValid;
767
- var sPart;
768
- var iWeek;
769
- var iLength = 0;
797
+ var sPart, bPartInvalid, bValid, iWeek, iLength = 0;
770
798
  if (oPart.digits < 3) {
771
799
  sPart = oParseHelper.findNumbers(sValue, 2);
772
800
  iLength = sPart.length;
773
801
  iWeek = parseInt(sPart) - 1;
774
- bValid = oParseHelper.checkValid(oPart.type, !sPart, oFormat);
802
+ bPartInvalid = !sPart || oConfig.exactLength && iLength < 2;
803
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
775
804
  } else {
776
805
  sPart = oFormat.oLocaleData.getCalendarWeek(oPart.digits === 3 ? 'narrow' : 'wide');
777
806
  sPart = sPart.replace('{0}', '([0-9]+)');
@@ -788,35 +817,21 @@ DateFormat.prototype.oSymbols = {
788
817
  valid: bValid,
789
818
  week: iWeek
790
819
  };
791
- }
792
- },
793
- 'W': {
794
- name: 'weekInMonth',
795
- format: function (oField, oDate) {
796
- return '';
797
820
  },
798
- parse: function () {
799
- return {};
821
+ isNumeric: function (iDigits) {
822
+ return iDigits < 3;
800
823
  }
801
- },
802
- 'D': {
803
- name: 'dayInYear',
804
- format: function (oField, oDate) {
805
- },
806
- parse: function () {
807
- return {};
808
- }
809
- },
810
- 'd': {
824
+ }),
825
+ 'W': DateFormat._createPatternSymbol({ name: 'weekInMonth' }),
826
+ 'D': DateFormat._createPatternSymbol({ name: 'dayInYear' }),
827
+ 'd': DateFormat._createPatternSymbol({
811
828
  name: 'day',
812
829
  format: function (oField, oDate) {
813
830
  var iDate = oDate.getUTCDate();
814
831
  return String(iDate).padStart(oField.digits, '0');
815
832
  },
816
833
  parse: function (sValue, oPart, oFormat, oConfig) {
817
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
818
- var bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
819
- var iDay = parseInt(sPart);
834
+ var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2)), bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2, bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat), iDay = parseInt(sPart);
820
835
  if (oConfig.strict && (iDay > 31 || iDay < 1)) {
821
836
  bValid = false;
822
837
  }
@@ -825,15 +840,16 @@ DateFormat.prototype.oSymbols = {
825
840
  length: sPart.length,
826
841
  valid: bValid
827
842
  };
828
- }
829
- },
830
- 'Q': {
843
+ },
844
+ isNumeric: true
845
+ }),
846
+ 'Q': DateFormat._createPatternSymbol({
831
847
  name: 'quarter',
832
848
  format: function (oField, oDate, bUTC, oFormat) {
833
849
  var iQuarter = oDate.getUTCQuarter();
834
- if (oField.digits == 3) {
850
+ if (oField.digits === 3) {
835
851
  return oFormat.aQuartersAbbrev[iQuarter];
836
- } else if (oField.digits == 4) {
852
+ } else if (oField.digits === 4) {
837
853
  return oFormat.aQuartersWide[iQuarter];
838
854
  } else if (oField.digits > 4) {
839
855
  return oFormat.aQuartersNarrow[iQuarter];
@@ -842,9 +858,7 @@ DateFormat.prototype.oSymbols = {
842
858
  }
843
859
  },
844
860
  parse: function (sValue, oPart, oFormat, oConfig) {
845
- var bValid;
846
- var iQuarter;
847
- var sPart;
861
+ var sPart, bPartInvalid, iQuarter, bValid;
848
862
  var aQuartersVariants = [
849
863
  oFormat.aQuartersWide,
850
864
  oFormat.aQuartersWideSt,
@@ -855,7 +869,8 @@ DateFormat.prototype.oSymbols = {
855
869
  ];
856
870
  if (oPart.digits < 3) {
857
871
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
858
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
872
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
873
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
859
874
  iQuarter = parseInt(sPart) - 1;
860
875
  if (oConfig.strict && iQuarter > 3) {
861
876
  bValid = false;
@@ -878,15 +893,18 @@ DateFormat.prototype.oSymbols = {
878
893
  quarter: iQuarter,
879
894
  valid: bValid
880
895
  };
896
+ },
897
+ isNumeric: function (iDigits) {
898
+ return iDigits < 3;
881
899
  }
882
- },
883
- 'q': {
900
+ }),
901
+ 'q': DateFormat._createPatternSymbol({
884
902
  name: 'quarterStandalone',
885
903
  format: function (oField, oDate, bUTC, oFormat) {
886
904
  var iQuarter = oDate.getUTCQuarter();
887
- if (oField.digits == 3) {
905
+ if (oField.digits === 3) {
888
906
  return oFormat.aQuartersAbbrevSt[iQuarter];
889
- } else if (oField.digits == 4) {
907
+ } else if (oField.digits === 4) {
890
908
  return oFormat.aQuartersWideSt[iQuarter];
891
909
  } else if (oField.digits > 4) {
892
910
  return oFormat.aQuartersNarrowSt[iQuarter];
@@ -895,9 +913,7 @@ DateFormat.prototype.oSymbols = {
895
913
  }
896
914
  },
897
915
  parse: function (sValue, oPart, oFormat, oConfig) {
898
- var bValid;
899
- var iQuarter;
900
- var sPart;
916
+ var sPart, bPartInvalid, iQuarter, bValid;
901
917
  var aQuartersVariants = [
902
918
  oFormat.aQuartersWide,
903
919
  oFormat.aQuartersWideSt,
@@ -908,7 +924,8 @@ DateFormat.prototype.oSymbols = {
908
924
  ];
909
925
  if (oPart.digits < 3) {
910
926
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
911
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
927
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
928
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
912
929
  iQuarter = parseInt(sPart) - 1;
913
930
  if (oConfig.strict && iQuarter > 3) {
914
931
  bValid = false;
@@ -931,26 +948,21 @@ DateFormat.prototype.oSymbols = {
931
948
  quarter: iQuarter,
932
949
  valid: bValid
933
950
  };
934
- }
935
- },
936
- 'F': {
937
- name: 'dayOfWeekInMonth',
938
- format: function (oField, oDate, oFormat) {
939
- return '';
940
951
  },
941
- parse: function () {
942
- return {};
952
+ isNumeric: function (iDigits) {
953
+ return iDigits < 3;
943
954
  }
944
- },
945
- 'E': {
955
+ }),
956
+ 'F': DateFormat._createPatternSymbol({ name: 'dayOfWeekInMonth' }),
957
+ 'E': DateFormat._createPatternSymbol({
946
958
  name: 'dayNameInWeek',
947
959
  format: function (oField, oDate, bUTC, oFormat) {
948
960
  var iDay = oDate.getUTCDay();
949
961
  if (oField.digits < 4) {
950
962
  return oFormat.aDaysAbbrev[iDay];
951
- } else if (oField.digits == 4) {
963
+ } else if (oField.digits === 4) {
952
964
  return oFormat.aDaysWide[iDay];
953
- } else if (oField.digits == 5) {
965
+ } else if (oField.digits === 5) {
954
966
  return oFormat.aDaysNarrow[iDay];
955
967
  } else {
956
968
  return oFormat.aDaysShort[iDay];
@@ -978,16 +990,16 @@ DateFormat.prototype.oSymbols = {
978
990
  }
979
991
  }
980
992
  }
981
- },
982
- 'c': {
993
+ }),
994
+ 'c': DateFormat._createPatternSymbol({
983
995
  name: 'dayNameInWeekStandalone',
984
996
  format: function (oField, oDate, bUTC, oFormat) {
985
997
  var iDay = oDate.getUTCDay();
986
998
  if (oField.digits < 4) {
987
999
  return oFormat.aDaysAbbrevSt[iDay];
988
- } else if (oField.digits == 4) {
1000
+ } else if (oField.digits === 4) {
989
1001
  return oFormat.aDaysWideSt[iDay];
990
- } else if (oField.digits == 5) {
1002
+ } else if (oField.digits === 5) {
991
1003
  return oFormat.aDaysNarrowSt[iDay];
992
1004
  } else {
993
1005
  return oFormat.aDaysShortSt[iDay];
@@ -1015,67 +1027,120 @@ DateFormat.prototype.oSymbols = {
1015
1027
  }
1016
1028
  }
1017
1029
  }
1018
- },
1019
- 'u': {
1030
+ }),
1031
+ 'u': DateFormat._createPatternSymbol({
1020
1032
  name: 'dayNumberOfWeek',
1021
1033
  format: function (oField, oDate, bUTC, oFormat) {
1022
1034
  var iDay = oDate.getUTCDay();
1023
1035
  return oFormat._adaptDayOfWeek(iDay);
1024
1036
  },
1025
1037
  parse: function (sValue, oPart, oFormat, oConfig) {
1026
- var sPart = oParseHelper.findNumbers(sValue, oPart.digits);
1038
+ var sPart = oParseHelper.findNumbers(sValue, oPart.digits), bPartInvalid = oConfig.exactLength && sPart.length !== oPart.digits;
1027
1039
  return {
1028
1040
  dayNumberOfWeek: parseInt(sPart),
1029
- length: sPart.length
1041
+ length: sPart.length,
1042
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat)
1030
1043
  };
1031
- }
1032
- },
1033
- 'a': {
1044
+ },
1045
+ isNumeric: true
1046
+ }),
1047
+ 'a': DateFormat._createPatternSymbol({
1034
1048
  name: 'amPmMarker',
1035
1049
  format: function (oField, oDate, bUTC, oFormat) {
1036
1050
  var iDayPeriod = oDate.getUTCDayPeriod();
1037
- return oFormat.aDayPeriods[iDayPeriod];
1051
+ if (oField.digits <= 3) {
1052
+ return oFormat.aDayPeriodsAbbrev[iDayPeriod];
1053
+ } else if (oField.digits === 4) {
1054
+ return oFormat.aDayPeriodsWide[iDayPeriod];
1055
+ } else {
1056
+ return oFormat.aDayPeriodsNarrow[iDayPeriod];
1057
+ }
1058
+ },
1059
+ parse: function (sValue, oPart, oFormat, oConfig, sTimezone) {
1060
+ var rAMPM, bAMPMAlternativeCase, oEntry, i, aMatch, normalize, aVariants, aDayPeriodsVariants = [
1061
+ oFormat.aDayPeriodsWide,
1062
+ oFormat.aDayPeriodsAbbrev,
1063
+ oFormat.aDayPeriodsNarrow
1064
+ ];
1065
+ rAMPM = /[aApP](?:\.)?[\x20\xA0]?[mM](?:\.)?/;
1066
+ aMatch = sValue.match(rAMPM);
1067
+ bAMPMAlternativeCase = aMatch && aMatch.index === 0;
1068
+ function normalize(sValue) {
1069
+ return sValue.replace(/[\x20\xA0]/g, '').replace(/\./g, '');
1070
+ }
1071
+ if (bAMPMAlternativeCase) {
1072
+ sValue = normalize(sValue);
1073
+ }
1074
+ for (i = 0; i < aDayPeriodsVariants.length; i += 1) {
1075
+ aVariants = aDayPeriodsVariants[i];
1076
+ if (bAMPMAlternativeCase) {
1077
+ aVariants = aVariants.map(normalize);
1078
+ }
1079
+ oEntry = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
1080
+ if (oEntry.index !== -1) {
1081
+ return {
1082
+ pm: oEntry.index === 1,
1083
+ length: bAMPMAlternativeCase ? aMatch[0].length : oEntry.length
1084
+ };
1085
+ }
1086
+ }
1087
+ return { valid: false };
1088
+ }
1089
+ }),
1090
+ 'B': DateFormat._createPatternSymbol({
1091
+ name: 'flexibleDayPeriod',
1092
+ format: function (oField, oDate, bUTC, oFormat) {
1093
+ var bContainsHour = oFormat.aFormatArray.some(function (oFormatElement) {
1094
+ return 'hHKk'.includes(oFormatElement.symbol);
1095
+ }), sFlexibleDayPeriod = oFormat.oLocaleData.getFlexibleDayPeriodOfTime(oDate.getUTCHours(), oDate.getUTCMinutes());
1096
+ if (bContainsHour) {
1097
+ if (oField.digits <= 3) {
1098
+ return oFormat.oFlexibleDayPeriodsAbbrev[sFlexibleDayPeriod];
1099
+ }
1100
+ if (oField.digits === 4) {
1101
+ return oFormat.oFlexibleDayPeriodsWide[sFlexibleDayPeriod];
1102
+ }
1103
+ return oFormat.oFlexibleDayPeriodsNarrow[sFlexibleDayPeriod];
1104
+ }
1105
+ if (oField.digits <= 3) {
1106
+ return oFormat.oFlexibleDayPeriodsAbbrevSt[sFlexibleDayPeriod];
1107
+ }
1108
+ if (oField.digits === 4) {
1109
+ return oFormat.oFlexibleDayPeriodsWideSt[sFlexibleDayPeriod];
1110
+ }
1111
+ return oFormat.oFlexibleDayPeriodsNarrowSt[sFlexibleDayPeriod];
1038
1112
  },
1039
1113
  parse: function (sValue, oPart, oFormat, oConfig) {
1040
- var bPM;
1041
- var iLength;
1042
- var sAM = oFormat.aDayPeriods[0], sPM = oFormat.aDayPeriods[1];
1043
- var rAMPM = /[aApP](?:\.)?[\x20\xA0]?[mM](?:\.)?/;
1044
- var aMatch = sValue.match(rAMPM);
1045
- var bVariant = aMatch && aMatch.index === 0;
1046
- if (bVariant) {
1047
- sValue = aMatch[0];
1048
- sAM = sAM.replace(/[\x20\xA0]/g, '');
1049
- sPM = sPM.replace(/[\x20\xA0]/g, '');
1050
- sValue = sValue.replace(/[\x20\xA0]/g, '');
1051
- sAM = sAM.replace(/\./g, '').toLowerCase();
1052
- sPM = sPM.replace(/\./g, '').toLowerCase();
1053
- sValue = sValue.replace(/\./g, '').toLowerCase();
1054
- }
1055
- if (sValue.indexOf(sAM) === 0) {
1056
- bPM = false;
1057
- iLength = bVariant ? aMatch[0].length : sAM.length;
1058
- } else if (sValue.indexOf(sPM) === 0) {
1059
- bPM = true;
1060
- iLength = bVariant ? aMatch[0].length : sPM.length;
1114
+ var i, oFound, oVariant, bContainsHour = oFormat.aFormatArray.some(function (oFormatElement) {
1115
+ return 'hHKk'.includes(oFormatElement.symbol);
1116
+ }), aFlexibleDayPeriodVariants = [
1117
+ oFormat.oFlexibleDayPeriodsWide,
1118
+ oFormat.oFlexibleDayPeriodsAbbrev,
1119
+ oFormat.oFlexibleDayPeriodsNarrow
1120
+ ];
1121
+ if (bContainsHour) {
1122
+ for (i = 0; i < aFlexibleDayPeriodVariants.length; i++) {
1123
+ oVariant = aFlexibleDayPeriodVariants[i];
1124
+ oFound = oParseHelper.findEntry(sValue, Object.values(oVariant), oFormat.oLocaleData.sCLDRLocaleId);
1125
+ if (oFound.index !== -1) {
1126
+ return {
1127
+ flexDayPeriod: Object.keys(oVariant)[oFound.index],
1128
+ length: oFound.length
1129
+ };
1130
+ }
1131
+ }
1061
1132
  }
1062
- return {
1063
- pm: bPM,
1064
- length: iLength
1065
- };
1133
+ return { valid: false };
1066
1134
  }
1067
- },
1068
- 'H': {
1135
+ }),
1136
+ 'H': DateFormat._createPatternSymbol({
1069
1137
  name: 'hour0_23',
1070
1138
  format: function (oField, oDate) {
1071
1139
  var iHours = oDate.getUTCHours();
1072
1140
  return String(iHours).padStart(oField.digits, '0');
1073
1141
  },
1074
1142
  parse: function (sValue, oPart, oFormat, oConfig) {
1075
- var bValid;
1076
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1077
- var iHours = parseInt(sPart);
1078
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1143
+ var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2)), iHours = parseInt(sPart), bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2, bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
1079
1144
  if (oConfig.strict && iHours > 23) {
1080
1145
  bValid = false;
1081
1146
  }
@@ -1084,9 +1149,10 @@ DateFormat.prototype.oSymbols = {
1084
1149
  length: sPart.length,
1085
1150
  valid: bValid
1086
1151
  };
1087
- }
1088
- },
1089
- 'k': {
1152
+ },
1153
+ isNumeric: true
1154
+ }),
1155
+ 'k': DateFormat._createPatternSymbol({
1090
1156
  name: 'hour1_24',
1091
1157
  format: function (oField, oDate) {
1092
1158
  var iHours = oDate.getUTCHours();
@@ -1094,11 +1160,8 @@ DateFormat.prototype.oSymbols = {
1094
1160
  return sHours.padStart(oField.digits, '0');
1095
1161
  },
1096
1162
  parse: function (sValue, oPart, oFormat, oConfig) {
1097
- var bValid;
1098
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1099
- var iHours = parseInt(sPart);
1100
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1101
- if (iHours == 24) {
1163
+ var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2)), iHours = parseInt(sPart), bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2, bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
1164
+ if (iHours === 24) {
1102
1165
  iHours = 0;
1103
1166
  }
1104
1167
  if (oConfig.strict && iHours > 23) {
@@ -1109,9 +1172,10 @@ DateFormat.prototype.oSymbols = {
1109
1172
  length: sPart.length,
1110
1173
  valid: bValid
1111
1174
  };
1112
- }
1113
- },
1114
- 'K': {
1175
+ },
1176
+ isNumeric: true
1177
+ }),
1178
+ 'K': DateFormat._createPatternSymbol({
1115
1179
  name: 'hour0_11',
1116
1180
  format: function (oField, oDate) {
1117
1181
  var iHours = oDate.getUTCHours();
@@ -1119,10 +1183,7 @@ DateFormat.prototype.oSymbols = {
1119
1183
  return sHours.padStart(oField.digits, '0');
1120
1184
  },
1121
1185
  parse: function (sValue, oPart, oFormat, oConfig) {
1122
- var bValid;
1123
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1124
- var iHours = parseInt(sPart);
1125
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1186
+ var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2)), iHours = parseInt(sPart), bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2, bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
1126
1187
  if (oConfig.strict && iHours > 11) {
1127
1188
  bValid = false;
1128
1189
  }
@@ -1131,16 +1192,17 @@ DateFormat.prototype.oSymbols = {
1131
1192
  length: sPart.length,
1132
1193
  valid: bValid
1133
1194
  };
1134
- }
1135
- },
1136
- 'h': {
1195
+ },
1196
+ isNumeric: true
1197
+ }),
1198
+ 'h': DateFormat._createPatternSymbol({
1137
1199
  name: 'hour1_12',
1138
1200
  format: function (oField, oDate) {
1139
1201
  var iHours = oDate.getUTCHours();
1140
1202
  var sHours;
1141
1203
  if (iHours > 12) {
1142
1204
  sHours = String(iHours - 12);
1143
- } else if (iHours == 0) {
1205
+ } else if (iHours === 0) {
1144
1206
  sHours = '12';
1145
1207
  } else {
1146
1208
  sHours = String(iHours);
@@ -1148,11 +1210,8 @@ DateFormat.prototype.oSymbols = {
1148
1210
  return sHours.padStart(oField.digits, '0');
1149
1211
  },
1150
1212
  parse: function (sValue, oPart, oFormat, oConfig) {
1151
- var bPM = oConfig.dateValue.pm;
1152
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1153
- var iHours = parseInt(sPart);
1154
- var bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1155
- if (iHours == 12) {
1213
+ var bPM = oConfig.dateValue.pm, sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2)), iHours = parseInt(sPart), bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2, bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
1214
+ if (iHours === 12) {
1156
1215
  iHours = 0;
1157
1216
  bPM = bPM === undefined ? true : bPM;
1158
1217
  }
@@ -1165,19 +1224,17 @@ DateFormat.prototype.oSymbols = {
1165
1224
  pm: bPM,
1166
1225
  valid: bValid
1167
1226
  };
1168
- }
1169
- },
1170
- 'm': {
1227
+ },
1228
+ isNumeric: true
1229
+ }),
1230
+ 'm': DateFormat._createPatternSymbol({
1171
1231
  name: 'minute',
1172
1232
  format: function (oField, oDate) {
1173
1233
  var iMinutes = oDate.getUTCMinutes();
1174
1234
  return String(iMinutes).padStart(oField.digits, '0');
1175
1235
  },
1176
1236
  parse: function (sValue, oPart, oFormat, oConfig) {
1177
- var bValid;
1178
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1179
- var iMinutes = parseInt(sPart);
1180
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1237
+ var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2)), iMinutes = parseInt(sPart), bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2, bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
1181
1238
  if (oConfig.strict && iMinutes > 59) {
1182
1239
  bValid = false;
1183
1240
  }
@@ -1186,19 +1243,17 @@ DateFormat.prototype.oSymbols = {
1186
1243
  minute: iMinutes,
1187
1244
  valid: bValid
1188
1245
  };
1189
- }
1190
- },
1191
- 's': {
1246
+ },
1247
+ isNumeric: true
1248
+ }),
1249
+ 's': DateFormat._createPatternSymbol({
1192
1250
  name: 'second',
1193
1251
  format: function (oField, oDate) {
1194
1252
  var iSeconds = oDate.getUTCSeconds();
1195
1253
  return String(iSeconds).padStart(oField.digits, '0');
1196
1254
  },
1197
1255
  parse: function (sValue, oPart, oFormat, oConfig) {
1198
- var bValid;
1199
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1200
- var iSeconds = parseInt(sPart);
1201
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1256
+ var iExpectedDigits = Math.max(oPart.digits, 2), sPart = oParseHelper.findNumbers(sValue, iExpectedDigits), bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < iExpectedDigits, iSeconds = parseInt(sPart), bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
1202
1257
  if (oConfig.strict && iSeconds > 59) {
1203
1258
  bValid = false;
1204
1259
  }
@@ -1207,9 +1262,10 @@ DateFormat.prototype.oSymbols = {
1207
1262
  second: iSeconds,
1208
1263
  valid: bValid
1209
1264
  };
1210
- }
1211
- },
1212
- 'S': {
1265
+ },
1266
+ isNumeric: true
1267
+ }),
1268
+ 'S': DateFormat._createPatternSymbol({
1213
1269
  name: 'fractionalsecond',
1214
1270
  format: function (oField, oDate) {
1215
1271
  var iMilliseconds = oDate.getUTCMilliseconds();
@@ -1220,18 +1276,19 @@ DateFormat.prototype.oSymbols = {
1220
1276
  return sFractionalseconds;
1221
1277
  },
1222
1278
  parse: function (sValue, oPart, oFormat, oConfig) {
1223
- var sPart = oParseHelper.findNumbers(sValue, oPart.digits);
1224
- var iLength = sPart.length;
1279
+ var sPart = oParseHelper.findNumbers(sValue, oPart.digits), iLength = sPart.length, bPartInvalid = oConfig.exactLength && iLength < oPart.digits;
1225
1280
  sPart = sPart.substr(0, 3);
1226
1281
  sPart = sPart.padEnd(3, '0');
1227
1282
  var iMilliseconds = parseInt(sPart);
1228
1283
  return {
1229
1284
  length: iLength,
1230
- millisecond: iMilliseconds
1285
+ millisecond: iMilliseconds,
1286
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat)
1231
1287
  };
1232
- }
1233
- },
1234
- 'z': {
1288
+ },
1289
+ isNumeric: true
1290
+ }),
1291
+ 'z': DateFormat._createPatternSymbol({
1235
1292
  name: 'timezoneGeneral',
1236
1293
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1237
1294
  if (oField.digits > 3 && oDate.getTimezoneLong && oDate.getTimezoneLong()) {
@@ -1245,7 +1302,7 @@ DateFormat.prototype.oSymbols = {
1245
1302
  var bPositiveOffset = iTimezoneOffset > 0;
1246
1303
  var iHourOffset = Math.floor(iTZOffset / 60);
1247
1304
  var iMinuteOffset = Math.floor(iTZOffset % 60);
1248
- if (!bUTC && iTZOffset != 0) {
1305
+ if (!bUTC && iTZOffset !== 0) {
1249
1306
  sTimeZone += bPositiveOffset ? '-' : '+';
1250
1307
  sTimeZone += String(iHourOffset).padStart(2, '0');
1251
1308
  sTimeZone += ':';
@@ -1279,8 +1336,8 @@ DateFormat.prototype.oSymbols = {
1279
1336
  tzDiff: iTZDiff
1280
1337
  };
1281
1338
  }
1282
- },
1283
- 'Z': {
1339
+ }),
1340
+ 'Z': DateFormat._createPatternSymbol({
1284
1341
  name: 'timezoneRFC822',
1285
1342
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1286
1343
  var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
@@ -1299,8 +1356,8 @@ DateFormat.prototype.oSymbols = {
1299
1356
  parse: function (sValue, oPart, oFormat, oConfig) {
1300
1357
  return oParseHelper.parseTZ(sValue, false);
1301
1358
  }
1302
- },
1303
- 'X': {
1359
+ }),
1360
+ 'X': DateFormat._createPatternSymbol({
1304
1361
  name: 'timezoneISO8601',
1305
1362
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1306
1363
  var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
@@ -1309,7 +1366,7 @@ DateFormat.prototype.oSymbols = {
1309
1366
  var iHourOffset = Math.floor(iTZOffset / 60);
1310
1367
  var iMinuteOffset = Math.floor(iTZOffset % 60);
1311
1368
  var sTimeZone = '';
1312
- if (!bUTC && iTZOffset != 0) {
1369
+ if (!bUTC && iTZOffset !== 0) {
1313
1370
  sTimeZone += bPositiveOffset ? '-' : '+';
1314
1371
  sTimeZone += String(iHourOffset).padStart(2, '0');
1315
1372
  if (oField.digits > 1 || iMinuteOffset > 0) {
@@ -1333,12 +1390,12 @@ DateFormat.prototype.oSymbols = {
1333
1390
  return oParseHelper.parseTZ(sValue, oPart.digits === 3 || oPart.digits === 5);
1334
1391
  }
1335
1392
  }
1336
- },
1337
- 'V': {
1393
+ }),
1394
+ 'V': DateFormat._createPatternSymbol({
1338
1395
  name: 'timezoneID',
1339
1396
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1340
1397
  if (!bUTC && oField.digits === 2) {
1341
- return sTimezone;
1398
+ return oFormat.oLocaleData.getTimezoneTranslations()[sTimezone] || sTimezone;
1342
1399
  }
1343
1400
  return '';
1344
1401
  },
@@ -1348,24 +1405,33 @@ DateFormat.prototype.oSymbols = {
1348
1405
  length: 0
1349
1406
  };
1350
1407
  if (oPart.digits === 2) {
1351
- if (sValue === sTimezone) {
1352
- oTimezoneParsed.timezone = sTimezone;
1353
- oTimezoneParsed.length = sTimezone.length;
1354
- return oTimezoneParsed;
1408
+ var mTimezoneTranslations = oFormat.oLocaleData.getTimezoneTranslations();
1409
+ if (sValue === mTimezoneTranslations[sTimezone]) {
1410
+ return {
1411
+ timezone: sTimezone,
1412
+ length: sValue.length
1413
+ };
1414
+ }
1415
+ var aTimezoneTranslations = Object.values(mTimezoneTranslations);
1416
+ var oTimezoneResult = oParseHelper.findEntry(sValue, aTimezoneTranslations, oFormat.oLocaleData.sCLDRLocaleId);
1417
+ if (oTimezoneResult.index !== -1) {
1418
+ return {
1419
+ timezone: Object.keys(mTimezoneTranslations)[oTimezoneResult.index],
1420
+ length: oTimezoneResult.length
1421
+ };
1355
1422
  }
1356
- if (sValue) {
1357
- var rIanaTimezone = new RegExp('([A-Za-z_])+([/][A-Za-z_]+)+');
1358
- var aResult = rIanaTimezone.exec(sValue);
1359
- if (aResult && aResult[0] && TimezoneUtil.isValidTimezone(aResult[0])) {
1360
- oTimezoneParsed.timezone = aResult[0];
1361
- oTimezoneParsed.length = aResult[0].length;
1362
- return oTimezoneParsed;
1423
+ var sCurrentValue = '';
1424
+ for (var i = 0; i < sValue.length; i++) {
1425
+ sCurrentValue += sValue[i];
1426
+ if (TimezoneUtil.isValidTimezone(sCurrentValue)) {
1427
+ oTimezoneParsed.timezone = sCurrentValue;
1428
+ oTimezoneParsed.length = sCurrentValue.length;
1363
1429
  }
1364
1430
  }
1365
1431
  }
1366
1432
  return oTimezoneParsed;
1367
1433
  }
1368
- }
1434
+ })
1369
1435
  };
1370
1436
  DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1371
1437
  if (this.oFormatOptions.relative) {
@@ -1383,7 +1449,7 @@ DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1383
1449
  aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this, sTimezone));
1384
1450
  }
1385
1451
  sResult = aBuffer.join('');
1386
- if (Core.getConfiguration().getOriginInfo()) {
1452
+ if (Configuration.getOriginInfo()) {
1387
1453
  sResult = new String(sResult);
1388
1454
  sResult.originInfo = {
1389
1455
  source: 'Common Locale Data Repository',
@@ -1409,7 +1475,7 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1409
1475
  if (bUTC === undefined) {
1410
1476
  bUTC = this.oFormatOptions.UTC;
1411
1477
  }
1412
- sTimezone = sTimezone || Core.getConfiguration().getTimezone();
1478
+ sTimezone = sTimezone || Configuration.getTimezone();
1413
1479
  if (Array.isArray(vJSDate)) {
1414
1480
  if (!this.oFormatOptions.interval) {
1415
1481
  Log.error('Non-interval DateFormat can\'t format more than one date instance.');
@@ -1441,7 +1507,7 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1441
1507
  } else {
1442
1508
  if (!isValidDateObject(vJSDate)) {
1443
1509
  if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE && this.oFormatOptions.pattern.includes('VV')) {
1444
- return sTimezone;
1510
+ return this.oLocaleData.getTimezoneTranslations()[sTimezone] || sTimezone;
1445
1511
  }
1446
1512
  Log.error('The given date instance isn\'t valid.');
1447
1513
  return '';
@@ -1453,7 +1519,7 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1453
1519
  vJSDate = convertToTimezone(vJSDate, sTimezone, bUTC);
1454
1520
  sResult = this._format(vJSDate, bUTC, sTimezone);
1455
1521
  }
1456
- if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1522
+ if (sCalendarType === CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1457
1523
  sResult = sResult.replace(/(^|[^\d])1年/g, '$1元年');
1458
1524
  }
1459
1525
  return sResult;
@@ -1519,21 +1585,28 @@ DateFormat.prototype._getGreatestDiffField = function (aDates) {
1519
1585
  return null;
1520
1586
  };
1521
1587
  DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict, sTimezone) {
1522
- var iIndex = 0, oPart, sSubValue, oResult;
1523
- var oDateValue = {
1524
- valid: true,
1525
- lastTimezonePatternSymbol: ''
1526
- };
1527
- var oParseConf = {
1528
- formatArray: aFormatArray,
1529
- dateValue: oDateValue,
1530
- strict: bStrict
1531
- };
1588
+ var sFlexibleDayPeriod, oNextPart, oPart, bPM, oPrevPart, oResult, sSubValue, oDateValue = {
1589
+ valid: true,
1590
+ lastTimezonePatternSymbol: ''
1591
+ }, iIndex = 0, oParseConf = {
1592
+ formatArray: aFormatArray,
1593
+ dateValue: oDateValue,
1594
+ strict: bStrict
1595
+ }, that = this;
1596
+ function getSymbol(oPart0) {
1597
+ return that.oSymbols[oPart0.symbol || ''];
1598
+ }
1599
+ function isNumeric(oPart0) {
1600
+ return !!oPart0 && getSymbol(oPart0).isNumeric(oPart0.digits);
1601
+ }
1532
1602
  for (var i = 0; i < aFormatArray.length; i++) {
1533
1603
  sSubValue = sValue.substr(iIndex);
1534
1604
  oPart = aFormatArray[i];
1605
+ oPrevPart = aFormatArray[i - 1];
1606
+ oNextPart = aFormatArray[i + 1];
1535
1607
  oParseConf.index = i;
1536
- oResult = this.oSymbols[oPart.symbol || ''].parse(sSubValue, oPart, this, oParseConf, sTimezone) || {};
1608
+ oParseConf.exactLength = isNumeric(oPart) && (isNumeric(oPrevPart) || isNumeric(oNextPart));
1609
+ oResult = getSymbol(oPart).parse(sSubValue, oPart, this, oParseConf, sTimezone) || {};
1537
1610
  if (oResult.tzDiff !== undefined || oResult.timezone) {
1538
1611
  oResult.lastTimezonePatternSymbol = oPart.symbol;
1539
1612
  }
@@ -1544,7 +1617,12 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict, sTi
1544
1617
  iIndex += oResult.length || 0;
1545
1618
  }
1546
1619
  oDateValue.index = iIndex;
1547
- if (oDateValue.pm) {
1620
+ bPM = oDateValue.pm;
1621
+ if (oDateValue.flexDayPeriod && oDateValue.hour * 60 + (oDateValue.minute || 0) < 720) {
1622
+ sFlexibleDayPeriod = this.oLocaleData.getFlexibleDayPeriodOfTime(oDateValue.hour + 12, oDateValue.minute || 0);
1623
+ bPM = oDateValue.flexDayPeriod === sFlexibleDayPeriod;
1624
+ }
1625
+ if (bPM) {
1548
1626
  oDateValue.hour += 12;
1549
1627
  }
1550
1628
  if (oDateValue.dayNumberOfWeek === undefined && oDateValue.dayOfWeek !== undefined) {
@@ -1601,13 +1679,24 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1601
1679
  }.bind(this));
1602
1680
  return aDateValues;
1603
1681
  };
1682
+ function getCalendarWeekParameter(oFormatOptions) {
1683
+ if (oFormatOptions.calendarWeekNumbering) {
1684
+ return oFormatOptions.calendarWeekNumbering;
1685
+ } else if (oFormatOptions.firstDayOfWeek !== undefined && oFormatOptions.minimalDaysInFirstWeek !== undefined) {
1686
+ return {
1687
+ firstDayOfWeek: oFormatOptions.firstDayOfWeek,
1688
+ minimalDaysInFirstWeek: oFormatOptions.minimalDaysInFirstWeek
1689
+ };
1690
+ }
1691
+ return undefined;
1692
+ }
1604
1693
  var convertToTimezone = function (oJSDate, sTimezone, bUTC) {
1605
1694
  if (!bUTC && isValidDateObject(oJSDate)) {
1606
1695
  return TimezoneUtil.convertToTimezone(oJSDate, sTimezone);
1607
1696
  }
1608
1697
  return oJSDate;
1609
1698
  };
1610
- var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone) {
1699
+ var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone, oFormatOptions, oLocale) {
1611
1700
  if (!oDateValue.valid) {
1612
1701
  return null;
1613
1702
  }
@@ -1628,7 +1717,7 @@ var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone
1628
1717
  oDate.setUTCWeek({
1629
1718
  year: oDateValue.weekYear || oDateValue.year,
1630
1719
  week: oDateValue.week
1631
- });
1720
+ }, oLocale, getCalendarWeekParameter(oFormatOptions));
1632
1721
  if (oDateValue.dayNumberOfWeek !== undefined) {
1633
1722
  oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1634
1723
  }
@@ -1643,7 +1732,7 @@ var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone
1643
1732
  }
1644
1733
  }
1645
1734
  if (oDateValue.tzDiff) {
1646
- oDate.setUTCSeconds((oDateValue.second || 0) + oDateValue.tzDiff);
1735
+ oDate.setUTCSeconds(oDate.getUTCSeconds() + oDateValue.tzDiff);
1647
1736
  }
1648
1737
  return oDate;
1649
1738
  };
@@ -1694,11 +1783,11 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1694
1783
  sValue = sValue == null ? '' : String(sValue).trim();
1695
1784
  var oDateValue;
1696
1785
  var sCalendarType = this.oFormatOptions.calendarType;
1697
- sTimezone = sTimezone || Core.getConfiguration().getTimezone();
1786
+ sTimezone = sTimezone || Configuration.getTimezone();
1698
1787
  if (bStrict === undefined) {
1699
1788
  bStrict = this.oFormatOptions.strictParsing;
1700
1789
  }
1701
- if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1790
+ if (sCalendarType === CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1702
1791
  sValue = sValue.replace(/元年/g, '1年');
1703
1792
  }
1704
1793
  if (!this.oFormatOptions.interval) {
@@ -1710,7 +1799,7 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1710
1799
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1711
1800
  oDateValue.valid = false;
1712
1801
  }
1713
- oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone);
1802
+ oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1714
1803
  if (oJSDate) {
1715
1804
  if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1716
1805
  var bShowTimezone = this.oFormatOptions.showTimezone === undefined || this.oFormatOptions.showTimezone;
@@ -1735,11 +1824,11 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1735
1824
  } else {
1736
1825
  var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict, sTimezone);
1737
1826
  var oJSDate1, oJSDate2;
1738
- if (aDateValues && aDateValues.length == 2) {
1827
+ if (aDateValues && aDateValues.length === 2) {
1739
1828
  var oDateValue1 = mergeWithoutOverwrite(aDateValues[0], aDateValues[1]);
1740
1829
  var oDateValue2 = mergeWithoutOverwrite(aDateValues[1], aDateValues[0]);
1741
- oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict, sTimezone);
1742
- oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict, sTimezone);
1830
+ oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1831
+ oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1743
1832
  if (oJSDate1 && oJSDate2) {
1744
1833
  if (this.oFormatOptions.singleIntervalValue && oJSDate1.getTime() === oJSDate2.getTime()) {
1745
1834
  return [
@@ -1762,7 +1851,7 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1762
1851
  }
1763
1852
  }
1764
1853
  }
1765
- if (!this.bIsFallback) {
1854
+ if (this.aFallbackFormats) {
1766
1855
  var vDate;
1767
1856
  this.aFallbackFormats.every(function (oFallbackFormat) {
1768
1857
  vDate = oFallbackFormat.parse(sValue, bUTCInputParameter, bStrict);
@@ -1794,20 +1883,20 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1794
1883
  for (i = 0; i < sPattern.length; i++) {
1795
1884
  var sCurChar = sPattern.charAt(i), sNextChar, sPrevChar, sPrevPrevChar;
1796
1885
  if (bQuoted) {
1797
- if (sCurChar == '\'') {
1886
+ if (sCurChar === '\'') {
1798
1887
  sPrevChar = sPattern.charAt(i - 1);
1799
1888
  sPrevPrevChar = sPattern.charAt(i - 2);
1800
1889
  sNextChar = sPattern.charAt(i + 1);
1801
- if (sPrevChar == '\'' && sPrevPrevChar != '\'') {
1890
+ if (sPrevChar === '\'' && sPrevPrevChar !== '\'') {
1802
1891
  bQuoted = false;
1803
- } else if (sNextChar == '\'') {
1892
+ } else if (sNextChar === '\'') {
1804
1893
  i += 1;
1805
1894
  } else {
1806
1895
  bQuoted = false;
1807
1896
  continue;
1808
1897
  }
1809
1898
  }
1810
- if (sState == 'text') {
1899
+ if (sState === 'text') {
1811
1900
  oCurrentObject.value += sCurChar;
1812
1901
  } else {
1813
1902
  oCurrentObject = {
@@ -1818,11 +1907,11 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1818
1907
  sState = 'text';
1819
1908
  }
1820
1909
  } else {
1821
- if (sCurChar == '\'') {
1910
+ if (sCurChar === '\'') {
1822
1911
  bQuoted = true;
1823
1912
  } else if (this.oSymbols[sCurChar]) {
1824
1913
  sNewState = this.oSymbols[sCurChar].name;
1825
- if (sState == sNewState) {
1914
+ if (sState === sNewState) {
1826
1915
  oCurrentObject.digits++;
1827
1916
  } else {
1828
1917
  oCurrentObject = {
@@ -1842,7 +1931,7 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1842
1931
  }
1843
1932
  }
1844
1933
  } else {
1845
- if (sState == 'text') {
1934
+ if (sState === 'text') {
1846
1935
  oCurrentObject.value += sCurChar;
1847
1936
  } else {
1848
1937
  oCurrentObject = {
@@ -1878,57 +1967,78 @@ DateFormat.prototype.parseRelative = function (sValue, bUTC) {
1878
1967
  }
1879
1968
  }
1880
1969
  function computeRelativeDate(iDiff, sScale) {
1881
- var iToday, oToday = new Date(), oJSDate;
1882
- if (bUTC) {
1883
- iToday = oToday.getTime();
1884
- } else {
1885
- iToday = Date.UTC(oToday.getFullYear(), oToday.getMonth(), oToday.getDate(), oToday.getHours(), oToday.getMinutes(), oToday.getSeconds(), oToday.getMilliseconds());
1886
- }
1887
- oJSDate = new Date(iToday);
1888
- switch (sScale) {
1889
- case 'second':
1890
- oJSDate.setUTCSeconds(oJSDate.getUTCSeconds() + iDiff);
1891
- break;
1892
- case 'minute':
1893
- oJSDate.setUTCMinutes(oJSDate.getUTCMinutes() + iDiff);
1894
- break;
1895
- case 'hour':
1896
- oJSDate.setUTCHours(oJSDate.getUTCHours() + iDiff);
1897
- break;
1898
- case 'day':
1899
- oJSDate.setUTCDate(oJSDate.getUTCDate() + iDiff);
1900
- break;
1901
- case 'week':
1902
- oJSDate.setUTCDate(oJSDate.getUTCDate() + iDiff * 7);
1903
- break;
1904
- case 'month':
1905
- oJSDate.setUTCMonth(oJSDate.getUTCMonth() + iDiff);
1906
- break;
1907
- case 'quarter':
1908
- oJSDate.setUTCMonth(oJSDate.getUTCMonth() + iDiff * 3);
1909
- break;
1910
- case 'year':
1911
- oJSDate.setUTCFullYear(oJSDate.getUTCFullYear() + iDiff);
1912
- break;
1913
- }
1970
+ var oResult = UI5Date.getInstance();
1914
1971
  if (bUTC) {
1915
- return oJSDate;
1972
+ oResult.setUTCFullYear(oResult.getFullYear(), oResult.getMonth(), oResult.getDate());
1973
+ oResult.setUTCHours(oResult.getHours(), oResult.getMinutes(), oResult.getSeconds(), oResult.getMilliseconds());
1974
+ switch (sScale) {
1975
+ case 'second':
1976
+ oResult.setUTCSeconds(oResult.getUTCSeconds() + iDiff);
1977
+ break;
1978
+ case 'minute':
1979
+ oResult.setUTCMinutes(oResult.getUTCMinutes() + iDiff);
1980
+ break;
1981
+ case 'hour':
1982
+ oResult.setUTCHours(oResult.getUTCHours() + iDiff);
1983
+ break;
1984
+ case 'day':
1985
+ oResult.setUTCDate(oResult.getUTCDate() + iDiff);
1986
+ break;
1987
+ case 'week':
1988
+ oResult.setUTCDate(oResult.getUTCDate() + iDiff * 7);
1989
+ break;
1990
+ case 'month':
1991
+ oResult.setUTCMonth(oResult.getUTCMonth() + iDiff);
1992
+ break;
1993
+ case 'quarter':
1994
+ oResult.setUTCMonth(oResult.getUTCMonth() + iDiff * 3);
1995
+ break;
1996
+ case 'year':
1997
+ oResult.setUTCFullYear(oResult.getUTCFullYear() + iDiff);
1998
+ break;
1999
+ }
1916
2000
  } else {
1917
- return new Date(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate(), oJSDate.getUTCHours(), oJSDate.getUTCMinutes(), oJSDate.getUTCSeconds(), oJSDate.getUTCMilliseconds());
2001
+ switch (sScale) {
2002
+ case 'second':
2003
+ oResult.setSeconds(oResult.getSeconds() + iDiff);
2004
+ break;
2005
+ case 'minute':
2006
+ oResult.setMinutes(oResult.getMinutes() + iDiff);
2007
+ break;
2008
+ case 'hour':
2009
+ oResult.setHours(oResult.getHours() + iDiff);
2010
+ break;
2011
+ case 'day':
2012
+ oResult.setDate(oResult.getDate() + iDiff);
2013
+ break;
2014
+ case 'week':
2015
+ oResult.setDate(oResult.getDate() + iDiff * 7);
2016
+ break;
2017
+ case 'month':
2018
+ oResult.setMonth(oResult.getMonth() + iDiff);
2019
+ break;
2020
+ case 'quarter':
2021
+ oResult.setMonth(oResult.getMonth() + iDiff * 3);
2022
+ break;
2023
+ case 'year':
2024
+ oResult.setFullYear(oResult.getFullYear() + iDiff);
2025
+ break;
2026
+ }
1918
2027
  }
2028
+ return oResult;
1919
2029
  }
1920
2030
  };
1921
2031
  DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange, sTimezone) {
1922
- var oToday = convertToTimezone(new Date(), sTimezone), oDateUTC, sScale = this.oFormatOptions.relativeScale || 'day', iDiff, sPattern, iDiffSeconds;
2032
+ var oDateUTC, iDiff, iDiffSeconds, sPattern, oToday = convertToTimezone(new Date(), sTimezone), sScale = this.oFormatOptions.relativeScale || 'day';
1923
2033
  iDiffSeconds = (oJSDate.getTime() - oToday.getTime()) / 1000;
1924
- if (this.oFormatOptions.relativeScale == 'auto') {
2034
+ if (this.oFormatOptions.relativeScale === 'auto') {
1925
2035
  sScale = this._getScale(iDiffSeconds, this.aRelativeScales);
1926
2036
  sScale = fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds);
1927
2037
  }
1928
2038
  if (!aRange) {
1929
2039
  aRange = this._mRanges[sScale];
1930
2040
  }
1931
- if (sScale == 'year' || sScale == 'month' || sScale == 'day') {
2041
+ if (sScale === 'year' || sScale === 'month' || sScale === 'day') {
1932
2042
  oToday = new Date(Date.UTC(oToday.getUTCFullYear(), oToday.getUTCMonth(), oToday.getUTCDate()));
1933
2043
  oDateUTC = new Date(0);
1934
2044
  oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
@@ -1938,7 +2048,7 @@ DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange, sTimezone
1938
2048
  oToday,
1939
2049
  oJSDate
1940
2050
  ]);
1941
- if (this.oFormatOptions.relativeScale != 'auto' && (iDiff < aRange[0] || iDiff > aRange[1])) {
2051
+ if (this.oFormatOptions.relativeScale !== 'auto' && (iDiff < aRange[0] || iDiff > aRange[1])) {
1942
2052
  return null;
1943
2053
  }
1944
2054
  sPattern = this.oLocaleData.getRelativePattern(sScale, iDiff, iDiffSeconds > 0, this.oFormatOptions.relativeStyle);
@@ -2015,7 +2125,7 @@ function fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds) {
2015
2125
  return sScale;
2016
2126
  }
2017
2127
  function cutDateFields(oDate, iStartIndex) {
2018
- var aFields = [
2128
+ var sMethodName, aFields = [
2019
2129
  'FullYear',
2020
2130
  'Month',
2021
2131
  'Date',
@@ -2023,8 +2133,7 @@ function cutDateFields(oDate, iStartIndex) {
2023
2133
  'Minutes',
2024
2134
  'Seconds',
2025
2135
  'Milliseconds'
2026
- ], sMethodName;
2027
- var oDateCopy = new Date(oDate.getTime());
2136
+ ], oDateCopy = new Date(oDate.getTime());
2028
2137
  for (var i = iStartIndex; i < aFields.length; i++) {
2029
2138
  sMethodName = 'setUTC' + aFields[iStartIndex];
2030
2139
  oDateCopy[sMethodName].apply(oDateCopy, [0]);
@@ -2067,7 +2176,12 @@ var mRelativeDiffs = {
2067
2176
  }
2068
2177
  };
2069
2178
  DateFormat.prototype._adaptDayOfWeek = function (iDayOfWeek) {
2070
- var iFirstDayOfWeek = LocaleData.getInstance(Core.getConfiguration().getFormatSettings().getFormatLocale()).getFirstDayOfWeek();
2179
+ var vCalendarWeekParameter = getCalendarWeekParameter(this.oFormatOptions), iFirstDayOfWeek;
2180
+ if (typeof vCalendarWeekParameter === 'object') {
2181
+ iFirstDayOfWeek = vCalendarWeekParameter.firstDayOfWeek;
2182
+ } else {
2183
+ iFirstDayOfWeek = CalendarUtils.getWeekConfigurationValues(vCalendarWeekParameter, this.oLocale).firstDayOfWeek;
2184
+ }
2071
2185
  var iDayNumberOfWeek = iDayOfWeek - (iFirstDayOfWeek - 1);
2072
2186
  if (iDayNumberOfWeek <= 0) {
2073
2187
  iDayNumberOfWeek += 7;