@ui5/webcomponents-localization 1.13.0-rc.0 → 1.13.0-rc.2

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 (101) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/dates/CalendarDate.d.ts +6 -4
  3. package/dist/dates/CalendarDate.js +8 -7
  4. package/dist/dates/CalendarDate.js.map +1 -1
  5. package/dist/dates/UI5Date.d.ts +6 -0
  6. package/dist/dates/UI5Date.js +7 -0
  7. package/dist/dates/UI5Date.js.map +1 -0
  8. package/dist/dates/UniversalDate.d.ts +2 -1
  9. package/dist/dates/UniversalDate.js.map +1 -1
  10. package/dist/dates/calculateWeekNumber.d.ts +2 -1
  11. package/dist/dates/calculateWeekNumber.js.map +1 -1
  12. package/dist/dates/getRoundedTimestamp.js +1 -0
  13. package/dist/dates/getRoundedTimestamp.js.map +1 -1
  14. package/dist/dates/getTodayUTCTimestamp.js +2 -1
  15. package/dist/dates/getTodayUTCTimestamp.js.map +1 -1
  16. package/dist/dates/transformDateToSecondaryType.js +3 -2
  17. package/dist/dates/transformDateToSecondaryType.js.map +1 -1
  18. package/dist/generated/assets/cldr/ar.json +173 -161
  19. package/dist/generated/assets/cldr/ar_EG.json +173 -161
  20. package/dist/generated/assets/cldr/ar_SA.json +172 -161
  21. package/dist/generated/assets/cldr/bg.json +131 -125
  22. package/dist/generated/assets/cldr/ca.json +29 -19
  23. package/dist/generated/assets/cldr/cs.json +8 -2
  24. package/dist/generated/assets/cldr/cy.json +92 -86
  25. package/dist/generated/assets/cldr/da.json +238 -232
  26. package/dist/generated/assets/cldr/de.json +28 -22
  27. package/dist/generated/assets/cldr/de_AT.json +18 -12
  28. package/dist/generated/assets/cldr/de_CH.json +28 -22
  29. package/dist/generated/assets/cldr/el.json +61 -55
  30. package/dist/generated/assets/cldr/el_CY.json +61 -55
  31. package/dist/generated/assets/cldr/en.json +8 -2
  32. package/dist/generated/assets/cldr/en_AU.json +160 -154
  33. package/dist/generated/assets/cldr/en_GB.json +132 -126
  34. package/dist/generated/assets/cldr/en_HK.json +160 -151
  35. package/dist/generated/assets/cldr/en_IE.json +159 -153
  36. package/dist/generated/assets/cldr/en_IN.json +159 -150
  37. package/dist/generated/assets/cldr/en_NZ.json +159 -153
  38. package/dist/generated/assets/cldr/en_PG.json +159 -153
  39. package/dist/generated/assets/cldr/en_SG.json +148 -139
  40. package/dist/generated/assets/cldr/en_ZA.json +156 -150
  41. package/dist/generated/assets/cldr/es.json +296 -289
  42. package/dist/generated/assets/cldr/es_AR.json +213 -206
  43. package/dist/generated/assets/cldr/es_BO.json +216 -209
  44. package/dist/generated/assets/cldr/es_CL.json +176 -169
  45. package/dist/generated/assets/cldr/es_CO.json +176 -169
  46. package/dist/generated/assets/cldr/es_MX.json +271 -264
  47. package/dist/generated/assets/cldr/es_PE.json +141 -134
  48. package/dist/generated/assets/cldr/es_UY.json +144 -137
  49. package/dist/generated/assets/cldr/es_VE.json +144 -137
  50. package/dist/generated/assets/cldr/et.json +175 -169
  51. package/dist/generated/assets/cldr/fa.json +245 -233
  52. package/dist/generated/assets/cldr/fi.json +148 -57
  53. package/dist/generated/assets/cldr/fr.json +19 -12
  54. package/dist/generated/assets/cldr/fr_BE.json +19 -12
  55. package/dist/generated/assets/cldr/fr_CA.json +18 -11
  56. package/dist/generated/assets/cldr/fr_CH.json +17 -10
  57. package/dist/generated/assets/cldr/fr_LU.json +19 -12
  58. package/dist/generated/assets/cldr/he.json +98 -86
  59. package/dist/generated/assets/cldr/hi.json +57 -48
  60. package/dist/generated/assets/cldr/hr.json +10 -4
  61. package/dist/generated/assets/cldr/hu.json +11 -5
  62. package/dist/generated/assets/cldr/id.json +83 -77
  63. package/dist/generated/assets/cldr/it.json +28 -21
  64. package/dist/generated/assets/cldr/it_CH.json +28 -21
  65. package/dist/generated/assets/cldr/ja.json +20 -12
  66. package/dist/generated/assets/cldr/kk.json +8 -2
  67. package/dist/generated/assets/cldr/ko.json +84 -75
  68. package/dist/generated/assets/cldr/lt.json +8 -2
  69. package/dist/generated/assets/cldr/lv.json +97 -91
  70. package/dist/generated/assets/cldr/ms.json +112 -106
  71. package/dist/generated/assets/cldr/nb.json +21 -15
  72. package/dist/generated/assets/cldr/nl.json +9 -3
  73. package/dist/generated/assets/cldr/nl_BE.json +9 -3
  74. package/dist/generated/assets/cldr/pl.json +28 -22
  75. package/dist/generated/assets/cldr/pt.json +255 -248
  76. package/dist/generated/assets/cldr/pt_PT.json +281 -274
  77. package/dist/generated/assets/cldr/ro.json +11 -5
  78. package/dist/generated/assets/cldr/ru.json +71 -65
  79. package/dist/generated/assets/cldr/ru_UA.json +70 -64
  80. package/dist/generated/assets/cldr/sk.json +9 -3
  81. package/dist/generated/assets/cldr/sl.json +197 -191
  82. package/dist/generated/assets/cldr/sr.json +67 -61
  83. package/dist/generated/assets/cldr/sr_Latn.json +70 -62
  84. package/dist/generated/assets/cldr/sv.json +189 -183
  85. package/dist/generated/assets/cldr/th.json +129 -120
  86. package/dist/generated/assets/cldr/tr.json +24 -18
  87. package/dist/generated/assets/cldr/uk.json +125 -119
  88. package/dist/generated/assets/cldr/vi.json +17 -11
  89. package/dist/generated/assets/cldr/zh_CN.json +185 -171
  90. package/dist/generated/assets/cldr/zh_HK.json +163 -149
  91. package/dist/generated/assets/cldr/zh_SG.json +162 -148
  92. package/dist/generated/assets/cldr/zh_TW.json +156 -125
  93. package/dist/sap/ui/core/Configuration.js +2 -1
  94. package/dist/sap/ui/core/Configuration.js.map +1 -1
  95. package/dist/sap/ui/core/LocaleData.js +73 -19
  96. package/dist/sap/ui/core/date/UI5Date.js +305 -0
  97. package/dist/sap/ui/core/date/UniversalDate.js +7 -6
  98. package/dist/sap/ui/core/format/DateFormat.js +307 -293
  99. package/dist/sap/ui/core/format/TimezoneUtil.js +7 -12
  100. package/package.json +7 -7
  101. package/used-modules.txt +1 -0
@@ -1,6 +1,7 @@
1
1
  import CalendarType from '../CalendarType.js';
2
2
  import Locale from '../Locale.js';
3
3
  import LocaleData from '../LocaleData.js';
4
+ import UI5Date from '../date/UI5Date.js';
4
5
  import UniversalDate from '../date/UniversalDate.js';
5
6
  import CalendarUtils from '../date/CalendarUtils.js';
6
7
  import CalendarWeekNumbering from '../date/CalendarWeekNumbering.js';
@@ -258,8 +259,9 @@ function createIntervalPatternWithNormalConnector(oFormat) {
258
259
  sPattern = sPattern.replace(/[^\{\}01 ]/, '-');
259
260
  return sPattern.replace(/\{(0|1)\}/g, oFormat.oFormatOptions.pattern);
260
261
  }
261
- DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
262
- 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);
263
265
  if (oFormatOptions instanceof Locale) {
264
266
  oLocale = oFormatOptions;
265
267
  oFormatOptions = undefined;
@@ -312,30 +314,27 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
312
314
  var sCommonConnectorPattern = createIntervalPatternWithNormalConnector(oFormat);
313
315
  oFormat.intervalPatterns.push(sCommonConnectorPattern);
314
316
  }
315
- if (!oFormat.oFormatOptions.fallback) {
316
- if (!oInfo.oFallbackFormats) {
317
- 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));
318
322
  }
319
- var sLocale = oLocale.toString(), sCalendarType = oFormat.oFormatOptions.calendarType, sKey = sLocale + '-' + sCalendarType, sPattern, aFallbackFormatOptions;
320
323
  if (oFormat.oFormatOptions.pattern && oInfo.bPatternFallbackWithoutDelimiter) {
321
- sKey = sKey + '-' + oFormat.oFormatOptions.pattern;
324
+ aFallbackFormatOptions = DateFormat._createFallbackOptionsWithoutDelimiter(oFormat.oFormatOptions.pattern).concat(aFallbackFormatOptions);
322
325
  }
323
- if (oFormat.oFormatOptions.interval) {
324
- sKey = sKey + '-' + 'interval';
325
- }
326
- var oFallbackFormats = oInfo.oFallbackFormats[sKey] ? Object.assign({}, oInfo.oFallbackFormats[sKey]) : undefined;
327
- if (!oFallbackFormats) {
328
- aFallbackFormatOptions = oInfo.aFallbackFormatOptions;
329
- if (oInfo.bShortFallbackFormatOptions) {
330
- sPattern = oInfo.getPattern(oFormat.oLocaleData, 'short');
331
- aFallbackFormatOptions = aFallbackFormatOptions.concat(DateFormat._createFallbackOptionsWithoutDelimiter(sPattern));
332
- }
333
- if (oFormat.oFormatOptions.pattern && oInfo.bPatternFallbackWithoutDelimiter) {
334
- aFallbackFormatOptions = DateFormat._createFallbackOptionsWithoutDelimiter(oFormat.oFormatOptions.pattern).concat(aFallbackFormatOptions);
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);
335
334
  }
336
- oFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, sCalendarType, oLocale, oInfo, oFormat.oFormatOptions);
337
- }
338
- oFormat.aFallbackFormats = oFallbackFormats;
335
+ return aFallbacks;
336
+ }, []);
337
+ oFormat.aFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, oFormat.oFormatOptions.calendarType, oLocale, oInfo, oFormat.oFormatOptions);
339
338
  }
340
339
  oFormat.oRequiredParts = oInfo.oRequiredParts;
341
340
  oFormat.aRelativeScales = oInfo.aRelativeScales;
@@ -394,10 +393,7 @@ DateFormat._createFallbackFormat = function (aFallbackFormatOptions, sCalendarTy
394
393
  oFormatOptions.interval = true;
395
394
  }
396
395
  oFormatOptions.calendarType = sCalendarType;
397
- oFormatOptions.fallback = true;
398
- var oFallbackFormat = DateFormat.createInstance(oFormatOptions, oLocale, oInfo);
399
- oFallbackFormat.bIsFallback = true;
400
- return oFallbackFormat;
396
+ return DateFormat.createInstance(oFormatOptions, oLocale, oInfo, true);
401
397
  });
402
398
  };
403
399
  DateFormat._createFallbackOptionsWithoutDelimiter = function (sBasePattern) {
@@ -433,9 +429,6 @@ var oParseHelper = {
433
429
  while (iLength < iMaxLength && this.isNumber(sValue.charCodeAt(iLength))) {
434
430
  iLength++;
435
431
  }
436
- if (typeof sValue !== 'string') {
437
- sValue = sValue.toString();
438
- }
439
432
  return sValue.substr(0, iLength);
440
433
  },
441
434
  startsWithIgnoreCase: function (sValue, sSubstring, sLocale) {
@@ -468,7 +461,7 @@ var oParseHelper = {
468
461
  },
469
462
  parseTZ: function (sValue, bColonSeparated) {
470
463
  var iLength = 0;
471
- var iTZFactor = sValue.charAt(0) == '+' ? -1 : 1;
464
+ var iTZFactor = sValue.charAt(0) === '+' ? -1 : 1;
472
465
  var sPart;
473
466
  iLength++;
474
467
  sPart = this.findNumbers(sValue.substr(iLength), 2);
@@ -488,14 +481,30 @@ var oParseHelper = {
488
481
  tzDiff: (iTZDiff + 60 * iTZDiffHour) * 60 * iTZFactor
489
482
  };
490
483
  },
491
- checkValid: function (sType, bPartInvalid, oFormat) {
492
- if (sType in oFormat.oRequiredParts && bPartInvalid) {
484
+ checkValid: function (sSymbolName, bPartInvalid, oFormat) {
485
+ if (sSymbolName in oFormat.oRequiredParts && bPartInvalid) {
493
486
  return false;
494
487
  }
488
+ return true;
495
489
  }
496
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
+ };
497
506
  DateFormat.prototype.oSymbols = {
498
- '': {
507
+ '': DateFormat._createPatternSymbol({
499
508
  name: 'text',
500
509
  format: function (oField, oDate) {
501
510
  return oField.value;
@@ -537,8 +546,8 @@ DateFormat.prototype.oSymbols = {
537
546
  return { valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat) };
538
547
  }
539
548
  }
540
- },
541
- 'G': {
549
+ }),
550
+ 'G': DateFormat._createPatternSymbol({
542
551
  name: 'era',
543
552
  format: function (oField, oDate, bUTC, oFormat) {
544
553
  var iEra = oDate.getUTCEra();
@@ -571,34 +580,35 @@ DateFormat.prototype.oSymbols = {
571
580
  valid: oParseHelper.checkValid(oPart.type, true, oFormat)
572
581
  };
573
582
  }
574
- },
575
- 'y': {
583
+ }),
584
+ 'y': DateFormat._createPatternSymbol({
576
585
  name: 'year',
577
586
  format: function (oField, oDate, bUTC, oFormat) {
578
587
  var iYear = oDate.getUTCFullYear();
579
588
  var sYear = String(iYear);
580
589
  var sCalendarType = oFormat.oFormatOptions.calendarType;
581
- if (oField.digits == 2 && sYear.length > 2) {
590
+ if (oField.digits === 2 && sYear.length > 2) {
582
591
  sYear = sYear.substr(sYear.length - 2);
583
592
  }
584
- if (sCalendarType != CalendarType.Japanese && oField.digits == 1 && iYear < 100) {
593
+ if (sCalendarType !== CalendarType.Japanese && oField.digits === 1 && iYear < 100) {
585
594
  sYear = sYear.padStart(4, '0');
586
595
  }
587
596
  return sYear.padStart(oField.digits, '0');
588
597
  },
589
598
  parse: function (sValue, oPart, oFormat, oConfig) {
590
- var sCalendarType = oFormat.oFormatOptions.calendarType;
591
- var sPart;
592
- if (oPart.digits == 1) {
593
- sPart = oParseHelper.findNumbers(sValue, 4);
594
- } else if (oPart.digits == 2) {
595
- 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;
596
604
  } else {
597
- sPart = oParseHelper.findNumbers(sValue, oPart.digits);
605
+ iExpectedDigits = oPart.digits;
598
606
  }
607
+ sPart = oParseHelper.findNumbers(sValue, iExpectedDigits);
608
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length !== iExpectedDigits;
599
609
  var iYear = parseInt(sPart);
600
- if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
601
- 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;
602
612
  if (iYearDiff < -70) {
603
613
  iYear += (iCurrentCentury + 1) * 100;
604
614
  } else if (iYearDiff < 30) {
@@ -609,40 +619,42 @@ DateFormat.prototype.oSymbols = {
609
619
  }
610
620
  return {
611
621
  length: sPart.length,
612
- valid: oParseHelper.checkValid(oPart.type, sPart === '', oFormat),
622
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat),
613
623
  year: iYear
614
624
  };
615
- }
616
- },
617
- 'Y': {
625
+ },
626
+ isNumeric: true
627
+ }),
628
+ 'Y': DateFormat._createPatternSymbol({
618
629
  name: 'weekYear',
619
630
  format: function (oField, oDate, bUTC, oFormat) {
620
631
  var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
621
632
  var iWeekYear = oWeek.year;
622
633
  var sWeekYear = String(iWeekYear);
623
634
  var sCalendarType = oFormat.oFormatOptions.calendarType;
624
- if (oField.digits == 2 && sWeekYear.length > 2) {
635
+ if (oField.digits === 2 && sWeekYear.length > 2) {
625
636
  sWeekYear = sWeekYear.substr(sWeekYear.length - 2);
626
637
  }
627
- if (sCalendarType != CalendarType.Japanese && oField.digits == 1 && iWeekYear < 100) {
638
+ if (sCalendarType !== CalendarType.Japanese && oField.digits === 1 && iWeekYear < 100) {
628
639
  sWeekYear = sWeekYear.padStart(4, '0');
629
640
  }
630
641
  return sWeekYear.padStart(oField.digits, '0');
631
642
  },
632
643
  parse: function (sValue, oPart, oFormat, oConfig) {
633
- var sCalendarType = oFormat.oFormatOptions.calendarType;
634
- var sPart;
635
- if (oPart.digits == 1) {
636
- sPart = oParseHelper.findNumbers(sValue, 4);
637
- } else if (oPart.digits == 2) {
638
- 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;
639
649
  } else {
640
- sPart = oParseHelper.findNumbers(sValue, oPart.digits);
650
+ iExpectedDigits = oPart.digits;
641
651
  }
652
+ sPart = oParseHelper.findNumbers(sValue, iExpectedDigits);
653
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length !== iExpectedDigits;
642
654
  var iYear = parseInt(sPart);
643
655
  var iWeekYear = iYear;
644
- if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
645
- 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;
646
658
  if (iYearDiff < -70) {
647
659
  iWeekYear += (iCurrentCentury + 1) * 100;
648
660
  } else if (iYearDiff < 30) {
@@ -653,19 +665,20 @@ DateFormat.prototype.oSymbols = {
653
665
  }
654
666
  return {
655
667
  length: sPart.length,
656
- valid: oParseHelper.checkValid(oPart.type, sPart === '', oFormat),
668
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat),
657
669
  year: iYear,
658
670
  weekYear: iWeekYear
659
671
  };
660
- }
661
- },
662
- 'M': {
672
+ },
673
+ isNumeric: true
674
+ }),
675
+ 'M': DateFormat._createPatternSymbol({
663
676
  name: 'month',
664
677
  format: function (oField, oDate, bUTC, oFormat) {
665
678
  var iMonth = oDate.getUTCMonth();
666
- if (oField.digits == 3) {
679
+ if (oField.digits === 3) {
667
680
  return oFormat.aMonthsAbbrev[iMonth];
668
- } else if (oField.digits == 4) {
681
+ } else if (oField.digits === 4) {
669
682
  return oFormat.aMonthsWide[iMonth];
670
683
  } else if (oField.digits > 4) {
671
684
  return oFormat.aMonthsNarrow[iMonth];
@@ -674,20 +687,18 @@ DateFormat.prototype.oSymbols = {
674
687
  }
675
688
  },
676
689
  parse: function (sValue, oPart, oFormat, oConfig) {
677
- var aMonthsVariants = [
678
- oFormat.aMonthsWide,
679
- oFormat.aMonthsWideSt,
680
- oFormat.aMonthsAbbrev,
681
- oFormat.aMonthsAbbrevSt,
682
- oFormat.aMonthsNarrow,
683
- oFormat.aMonthsNarrowSt
684
- ];
685
- var bValid;
686
- var iMonth;
687
- 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
+ ];
688
698
  if (oPart.digits < 3) {
689
699
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
690
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
700
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
701
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
691
702
  iMonth = parseInt(sPart) - 1;
692
703
  if (oConfig.strict && (iMonth > 11 || iMonth < 0)) {
693
704
  bValid = false;
@@ -710,15 +721,18 @@ DateFormat.prototype.oSymbols = {
710
721
  length: sPart ? sPart.length : 0,
711
722
  valid: bValid
712
723
  };
724
+ },
725
+ isNumeric: function (iDigits) {
726
+ return iDigits < 3;
713
727
  }
714
- },
715
- 'L': {
728
+ }),
729
+ 'L': DateFormat._createPatternSymbol({
716
730
  name: 'monthStandalone',
717
731
  format: function (oField, oDate, bUTC, oFormat) {
718
732
  var iMonth = oDate.getUTCMonth();
719
- if (oField.digits == 3) {
733
+ if (oField.digits === 3) {
720
734
  return oFormat.aMonthsAbbrevSt[iMonth];
721
- } else if (oField.digits == 4) {
735
+ } else if (oField.digits === 4) {
722
736
  return oFormat.aMonthsWideSt[iMonth];
723
737
  } else if (oField.digits > 4) {
724
738
  return oFormat.aMonthsNarrowSt[iMonth];
@@ -727,20 +741,18 @@ DateFormat.prototype.oSymbols = {
727
741
  }
728
742
  },
729
743
  parse: function (sValue, oPart, oFormat, oConfig) {
730
- var aMonthsVariants = [
731
- oFormat.aMonthsWide,
732
- oFormat.aMonthsWideSt,
733
- oFormat.aMonthsAbbrev,
734
- oFormat.aMonthsAbbrevSt,
735
- oFormat.aMonthsNarrow,
736
- oFormat.aMonthsNarrowSt
737
- ];
738
- var bValid;
739
- var iMonth;
740
- 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
+ ];
741
752
  if (oPart.digits < 3) {
742
753
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
743
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
754
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
755
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
744
756
  iMonth = parseInt(sPart) - 1;
745
757
  if (oConfig.strict && (iMonth > 11 || iMonth < 0)) {
746
758
  bValid = false;
@@ -763,9 +775,12 @@ DateFormat.prototype.oSymbols = {
763
775
  length: sPart ? sPart.length : 0,
764
776
  valid: bValid
765
777
  };
778
+ },
779
+ isNumeric: function (iDigits) {
780
+ return iDigits < 3;
766
781
  }
767
- },
768
- 'w': {
782
+ }),
783
+ 'w': DateFormat._createPatternSymbol({
769
784
  name: 'weekInYear',
770
785
  format: function (oField, oDate, bUTC, oFormat) {
771
786
  var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
@@ -779,15 +794,13 @@ DateFormat.prototype.oSymbols = {
779
794
  return sWeek;
780
795
  },
781
796
  parse: function (sValue, oPart, oFormat, oConfig) {
782
- var bValid;
783
- var sPart;
784
- var iWeek;
785
- var iLength = 0;
797
+ var sPart, bPartInvalid, bValid, iWeek, iLength = 0;
786
798
  if (oPart.digits < 3) {
787
799
  sPart = oParseHelper.findNumbers(sValue, 2);
788
800
  iLength = sPart.length;
789
801
  iWeek = parseInt(sPart) - 1;
790
- bValid = oParseHelper.checkValid(oPart.type, !sPart, oFormat);
802
+ bPartInvalid = !sPart || oConfig.exactLength && iLength < 2;
803
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
791
804
  } else {
792
805
  sPart = oFormat.oLocaleData.getCalendarWeek(oPart.digits === 3 ? 'narrow' : 'wide');
793
806
  sPart = sPart.replace('{0}', '([0-9]+)');
@@ -804,35 +817,21 @@ DateFormat.prototype.oSymbols = {
804
817
  valid: bValid,
805
818
  week: iWeek
806
819
  };
807
- }
808
- },
809
- 'W': {
810
- name: 'weekInMonth',
811
- format: function (oField, oDate) {
812
- return '';
813
820
  },
814
- parse: function () {
815
- return {};
821
+ isNumeric: function (iDigits) {
822
+ return iDigits < 3;
816
823
  }
817
- },
818
- 'D': {
819
- name: 'dayInYear',
820
- format: function (oField, oDate) {
821
- },
822
- parse: function () {
823
- return {};
824
- }
825
- },
826
- 'd': {
824
+ }),
825
+ 'W': DateFormat._createPatternSymbol({ name: 'weekInMonth' }),
826
+ 'D': DateFormat._createPatternSymbol({ name: 'dayInYear' }),
827
+ 'd': DateFormat._createPatternSymbol({
827
828
  name: 'day',
828
829
  format: function (oField, oDate) {
829
830
  var iDate = oDate.getUTCDate();
830
831
  return String(iDate).padStart(oField.digits, '0');
831
832
  },
832
833
  parse: function (sValue, oPart, oFormat, oConfig) {
833
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
834
- var bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
835
- 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);
836
835
  if (oConfig.strict && (iDay > 31 || iDay < 1)) {
837
836
  bValid = false;
838
837
  }
@@ -841,15 +840,16 @@ DateFormat.prototype.oSymbols = {
841
840
  length: sPart.length,
842
841
  valid: bValid
843
842
  };
844
- }
845
- },
846
- 'Q': {
843
+ },
844
+ isNumeric: true
845
+ }),
846
+ 'Q': DateFormat._createPatternSymbol({
847
847
  name: 'quarter',
848
848
  format: function (oField, oDate, bUTC, oFormat) {
849
849
  var iQuarter = oDate.getUTCQuarter();
850
- if (oField.digits == 3) {
850
+ if (oField.digits === 3) {
851
851
  return oFormat.aQuartersAbbrev[iQuarter];
852
- } else if (oField.digits == 4) {
852
+ } else if (oField.digits === 4) {
853
853
  return oFormat.aQuartersWide[iQuarter];
854
854
  } else if (oField.digits > 4) {
855
855
  return oFormat.aQuartersNarrow[iQuarter];
@@ -858,9 +858,7 @@ DateFormat.prototype.oSymbols = {
858
858
  }
859
859
  },
860
860
  parse: function (sValue, oPart, oFormat, oConfig) {
861
- var bValid;
862
- var iQuarter;
863
- var sPart;
861
+ var sPart, bPartInvalid, iQuarter, bValid;
864
862
  var aQuartersVariants = [
865
863
  oFormat.aQuartersWide,
866
864
  oFormat.aQuartersWideSt,
@@ -871,7 +869,8 @@ DateFormat.prototype.oSymbols = {
871
869
  ];
872
870
  if (oPart.digits < 3) {
873
871
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
874
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
872
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
873
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
875
874
  iQuarter = parseInt(sPart) - 1;
876
875
  if (oConfig.strict && iQuarter > 3) {
877
876
  bValid = false;
@@ -894,15 +893,18 @@ DateFormat.prototype.oSymbols = {
894
893
  quarter: iQuarter,
895
894
  valid: bValid
896
895
  };
896
+ },
897
+ isNumeric: function (iDigits) {
898
+ return iDigits < 3;
897
899
  }
898
- },
899
- 'q': {
900
+ }),
901
+ 'q': DateFormat._createPatternSymbol({
900
902
  name: 'quarterStandalone',
901
903
  format: function (oField, oDate, bUTC, oFormat) {
902
904
  var iQuarter = oDate.getUTCQuarter();
903
- if (oField.digits == 3) {
905
+ if (oField.digits === 3) {
904
906
  return oFormat.aQuartersAbbrevSt[iQuarter];
905
- } else if (oField.digits == 4) {
907
+ } else if (oField.digits === 4) {
906
908
  return oFormat.aQuartersWideSt[iQuarter];
907
909
  } else if (oField.digits > 4) {
908
910
  return oFormat.aQuartersNarrowSt[iQuarter];
@@ -911,9 +913,7 @@ DateFormat.prototype.oSymbols = {
911
913
  }
912
914
  },
913
915
  parse: function (sValue, oPart, oFormat, oConfig) {
914
- var bValid;
915
- var iQuarter;
916
- var sPart;
916
+ var sPart, bPartInvalid, iQuarter, bValid;
917
917
  var aQuartersVariants = [
918
918
  oFormat.aQuartersWide,
919
919
  oFormat.aQuartersWideSt,
@@ -924,7 +924,8 @@ DateFormat.prototype.oSymbols = {
924
924
  ];
925
925
  if (oPart.digits < 3) {
926
926
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
927
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
927
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
928
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
928
929
  iQuarter = parseInt(sPart) - 1;
929
930
  if (oConfig.strict && iQuarter > 3) {
930
931
  bValid = false;
@@ -947,26 +948,21 @@ DateFormat.prototype.oSymbols = {
947
948
  quarter: iQuarter,
948
949
  valid: bValid
949
950
  };
950
- }
951
- },
952
- 'F': {
953
- name: 'dayOfWeekInMonth',
954
- format: function (oField, oDate, oFormat) {
955
- return '';
956
951
  },
957
- parse: function () {
958
- return {};
952
+ isNumeric: function (iDigits) {
953
+ return iDigits < 3;
959
954
  }
960
- },
961
- 'E': {
955
+ }),
956
+ 'F': DateFormat._createPatternSymbol({ name: 'dayOfWeekInMonth' }),
957
+ 'E': DateFormat._createPatternSymbol({
962
958
  name: 'dayNameInWeek',
963
959
  format: function (oField, oDate, bUTC, oFormat) {
964
960
  var iDay = oDate.getUTCDay();
965
961
  if (oField.digits < 4) {
966
962
  return oFormat.aDaysAbbrev[iDay];
967
- } else if (oField.digits == 4) {
963
+ } else if (oField.digits === 4) {
968
964
  return oFormat.aDaysWide[iDay];
969
- } else if (oField.digits == 5) {
965
+ } else if (oField.digits === 5) {
970
966
  return oFormat.aDaysNarrow[iDay];
971
967
  } else {
972
968
  return oFormat.aDaysShort[iDay];
@@ -994,16 +990,16 @@ DateFormat.prototype.oSymbols = {
994
990
  }
995
991
  }
996
992
  }
997
- },
998
- 'c': {
993
+ }),
994
+ 'c': DateFormat._createPatternSymbol({
999
995
  name: 'dayNameInWeekStandalone',
1000
996
  format: function (oField, oDate, bUTC, oFormat) {
1001
997
  var iDay = oDate.getUTCDay();
1002
998
  if (oField.digits < 4) {
1003
999
  return oFormat.aDaysAbbrevSt[iDay];
1004
- } else if (oField.digits == 4) {
1000
+ } else if (oField.digits === 4) {
1005
1001
  return oFormat.aDaysWideSt[iDay];
1006
- } else if (oField.digits == 5) {
1002
+ } else if (oField.digits === 5) {
1007
1003
  return oFormat.aDaysNarrowSt[iDay];
1008
1004
  } else {
1009
1005
  return oFormat.aDaysShortSt[iDay];
@@ -1031,22 +1027,24 @@ DateFormat.prototype.oSymbols = {
1031
1027
  }
1032
1028
  }
1033
1029
  }
1034
- },
1035
- 'u': {
1030
+ }),
1031
+ 'u': DateFormat._createPatternSymbol({
1036
1032
  name: 'dayNumberOfWeek',
1037
1033
  format: function (oField, oDate, bUTC, oFormat) {
1038
1034
  var iDay = oDate.getUTCDay();
1039
1035
  return oFormat._adaptDayOfWeek(iDay);
1040
1036
  },
1041
1037
  parse: function (sValue, oPart, oFormat, oConfig) {
1042
- var sPart = oParseHelper.findNumbers(sValue, oPart.digits);
1038
+ var sPart = oParseHelper.findNumbers(sValue, oPart.digits), bPartInvalid = oConfig.exactLength && sPart.length !== oPart.digits;
1043
1039
  return {
1044
1040
  dayNumberOfWeek: parseInt(sPart),
1045
- length: sPart.length
1041
+ length: sPart.length,
1042
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat)
1046
1043
  };
1047
- }
1048
- },
1049
- 'a': {
1044
+ },
1045
+ isNumeric: true
1046
+ }),
1047
+ 'a': DateFormat._createPatternSymbol({
1050
1048
  name: 'amPmMarker',
1051
1049
  format: function (oField, oDate, bUTC, oFormat) {
1052
1050
  var iDayPeriod = oDate.getUTCDayPeriod();
@@ -1088,8 +1086,8 @@ DateFormat.prototype.oSymbols = {
1088
1086
  }
1089
1087
  return { valid: false };
1090
1088
  }
1091
- },
1092
- 'B': {
1089
+ }),
1090
+ 'B': DateFormat._createPatternSymbol({
1093
1091
  name: 'flexibleDayPeriod',
1094
1092
  format: function (oField, oDate, bUTC, oFormat) {
1095
1093
  var bContainsHour = oFormat.aFormatArray.some(function (oFormatElement) {
@@ -1134,18 +1132,15 @@ DateFormat.prototype.oSymbols = {
1134
1132
  }
1135
1133
  return { valid: false };
1136
1134
  }
1137
- },
1138
- 'H': {
1135
+ }),
1136
+ 'H': DateFormat._createPatternSymbol({
1139
1137
  name: 'hour0_23',
1140
1138
  format: function (oField, oDate) {
1141
1139
  var iHours = oDate.getUTCHours();
1142
1140
  return String(iHours).padStart(oField.digits, '0');
1143
1141
  },
1144
1142
  parse: function (sValue, oPart, oFormat, oConfig) {
1145
- var bValid;
1146
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1147
- var iHours = parseInt(sPart);
1148
- 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);
1149
1144
  if (oConfig.strict && iHours > 23) {
1150
1145
  bValid = false;
1151
1146
  }
@@ -1154,9 +1149,10 @@ DateFormat.prototype.oSymbols = {
1154
1149
  length: sPart.length,
1155
1150
  valid: bValid
1156
1151
  };
1157
- }
1158
- },
1159
- 'k': {
1152
+ },
1153
+ isNumeric: true
1154
+ }),
1155
+ 'k': DateFormat._createPatternSymbol({
1160
1156
  name: 'hour1_24',
1161
1157
  format: function (oField, oDate) {
1162
1158
  var iHours = oDate.getUTCHours();
@@ -1164,11 +1160,8 @@ DateFormat.prototype.oSymbols = {
1164
1160
  return sHours.padStart(oField.digits, '0');
1165
1161
  },
1166
1162
  parse: function (sValue, oPart, oFormat, oConfig) {
1167
- var bValid;
1168
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1169
- var iHours = parseInt(sPart);
1170
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1171
- 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) {
1172
1165
  iHours = 0;
1173
1166
  }
1174
1167
  if (oConfig.strict && iHours > 23) {
@@ -1179,9 +1172,10 @@ DateFormat.prototype.oSymbols = {
1179
1172
  length: sPart.length,
1180
1173
  valid: bValid
1181
1174
  };
1182
- }
1183
- },
1184
- 'K': {
1175
+ },
1176
+ isNumeric: true
1177
+ }),
1178
+ 'K': DateFormat._createPatternSymbol({
1185
1179
  name: 'hour0_11',
1186
1180
  format: function (oField, oDate) {
1187
1181
  var iHours = oDate.getUTCHours();
@@ -1189,10 +1183,7 @@ DateFormat.prototype.oSymbols = {
1189
1183
  return sHours.padStart(oField.digits, '0');
1190
1184
  },
1191
1185
  parse: function (sValue, oPart, oFormat, oConfig) {
1192
- var bValid;
1193
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1194
- var iHours = parseInt(sPart);
1195
- 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);
1196
1187
  if (oConfig.strict && iHours > 11) {
1197
1188
  bValid = false;
1198
1189
  }
@@ -1201,16 +1192,17 @@ DateFormat.prototype.oSymbols = {
1201
1192
  length: sPart.length,
1202
1193
  valid: bValid
1203
1194
  };
1204
- }
1205
- },
1206
- 'h': {
1195
+ },
1196
+ isNumeric: true
1197
+ }),
1198
+ 'h': DateFormat._createPatternSymbol({
1207
1199
  name: 'hour1_12',
1208
1200
  format: function (oField, oDate) {
1209
1201
  var iHours = oDate.getUTCHours();
1210
1202
  var sHours;
1211
1203
  if (iHours > 12) {
1212
1204
  sHours = String(iHours - 12);
1213
- } else if (iHours == 0) {
1205
+ } else if (iHours === 0) {
1214
1206
  sHours = '12';
1215
1207
  } else {
1216
1208
  sHours = String(iHours);
@@ -1218,11 +1210,8 @@ DateFormat.prototype.oSymbols = {
1218
1210
  return sHours.padStart(oField.digits, '0');
1219
1211
  },
1220
1212
  parse: function (sValue, oPart, oFormat, oConfig) {
1221
- var bPM = oConfig.dateValue.pm;
1222
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1223
- var iHours = parseInt(sPart);
1224
- var bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
1225
- 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) {
1226
1215
  iHours = 0;
1227
1216
  bPM = bPM === undefined ? true : bPM;
1228
1217
  }
@@ -1235,19 +1224,17 @@ DateFormat.prototype.oSymbols = {
1235
1224
  pm: bPM,
1236
1225
  valid: bValid
1237
1226
  };
1238
- }
1239
- },
1240
- 'm': {
1227
+ },
1228
+ isNumeric: true
1229
+ }),
1230
+ 'm': DateFormat._createPatternSymbol({
1241
1231
  name: 'minute',
1242
1232
  format: function (oField, oDate) {
1243
1233
  var iMinutes = oDate.getUTCMinutes();
1244
1234
  return String(iMinutes).padStart(oField.digits, '0');
1245
1235
  },
1246
1236
  parse: function (sValue, oPart, oFormat, oConfig) {
1247
- var bValid;
1248
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1249
- var iMinutes = parseInt(sPart);
1250
- 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);
1251
1238
  if (oConfig.strict && iMinutes > 59) {
1252
1239
  bValid = false;
1253
1240
  }
@@ -1256,19 +1243,17 @@ DateFormat.prototype.oSymbols = {
1256
1243
  minute: iMinutes,
1257
1244
  valid: bValid
1258
1245
  };
1259
- }
1260
- },
1261
- 's': {
1246
+ },
1247
+ isNumeric: true
1248
+ }),
1249
+ 's': DateFormat._createPatternSymbol({
1262
1250
  name: 'second',
1263
1251
  format: function (oField, oDate) {
1264
1252
  var iSeconds = oDate.getUTCSeconds();
1265
1253
  return String(iSeconds).padStart(oField.digits, '0');
1266
1254
  },
1267
1255
  parse: function (sValue, oPart, oFormat, oConfig) {
1268
- var bValid;
1269
- var sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
1270
- var iSeconds = parseInt(sPart);
1271
- 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);
1272
1257
  if (oConfig.strict && iSeconds > 59) {
1273
1258
  bValid = false;
1274
1259
  }
@@ -1277,9 +1262,10 @@ DateFormat.prototype.oSymbols = {
1277
1262
  second: iSeconds,
1278
1263
  valid: bValid
1279
1264
  };
1280
- }
1281
- },
1282
- 'S': {
1265
+ },
1266
+ isNumeric: true
1267
+ }),
1268
+ 'S': DateFormat._createPatternSymbol({
1283
1269
  name: 'fractionalsecond',
1284
1270
  format: function (oField, oDate) {
1285
1271
  var iMilliseconds = oDate.getUTCMilliseconds();
@@ -1290,18 +1276,19 @@ DateFormat.prototype.oSymbols = {
1290
1276
  return sFractionalseconds;
1291
1277
  },
1292
1278
  parse: function (sValue, oPart, oFormat, oConfig) {
1293
- var sPart = oParseHelper.findNumbers(sValue, oPart.digits);
1294
- var iLength = sPart.length;
1279
+ var sPart = oParseHelper.findNumbers(sValue, oPart.digits), iLength = sPart.length, bPartInvalid = oConfig.exactLength && iLength < oPart.digits;
1295
1280
  sPart = sPart.substr(0, 3);
1296
1281
  sPart = sPart.padEnd(3, '0');
1297
1282
  var iMilliseconds = parseInt(sPart);
1298
1283
  return {
1299
1284
  length: iLength,
1300
- millisecond: iMilliseconds
1285
+ millisecond: iMilliseconds,
1286
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat)
1301
1287
  };
1302
- }
1303
- },
1304
- 'z': {
1288
+ },
1289
+ isNumeric: true
1290
+ }),
1291
+ 'z': DateFormat._createPatternSymbol({
1305
1292
  name: 'timezoneGeneral',
1306
1293
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1307
1294
  if (oField.digits > 3 && oDate.getTimezoneLong && oDate.getTimezoneLong()) {
@@ -1315,7 +1302,7 @@ DateFormat.prototype.oSymbols = {
1315
1302
  var bPositiveOffset = iTimezoneOffset > 0;
1316
1303
  var iHourOffset = Math.floor(iTZOffset / 60);
1317
1304
  var iMinuteOffset = Math.floor(iTZOffset % 60);
1318
- if (!bUTC && iTZOffset != 0) {
1305
+ if (!bUTC && iTZOffset !== 0) {
1319
1306
  sTimeZone += bPositiveOffset ? '-' : '+';
1320
1307
  sTimeZone += String(iHourOffset).padStart(2, '0');
1321
1308
  sTimeZone += ':';
@@ -1349,8 +1336,8 @@ DateFormat.prototype.oSymbols = {
1349
1336
  tzDiff: iTZDiff
1350
1337
  };
1351
1338
  }
1352
- },
1353
- 'Z': {
1339
+ }),
1340
+ 'Z': DateFormat._createPatternSymbol({
1354
1341
  name: 'timezoneRFC822',
1355
1342
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1356
1343
  var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
@@ -1369,8 +1356,8 @@ DateFormat.prototype.oSymbols = {
1369
1356
  parse: function (sValue, oPart, oFormat, oConfig) {
1370
1357
  return oParseHelper.parseTZ(sValue, false);
1371
1358
  }
1372
- },
1373
- 'X': {
1359
+ }),
1360
+ 'X': DateFormat._createPatternSymbol({
1374
1361
  name: 'timezoneISO8601',
1375
1362
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1376
1363
  var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
@@ -1379,7 +1366,7 @@ DateFormat.prototype.oSymbols = {
1379
1366
  var iHourOffset = Math.floor(iTZOffset / 60);
1380
1367
  var iMinuteOffset = Math.floor(iTZOffset % 60);
1381
1368
  var sTimeZone = '';
1382
- if (!bUTC && iTZOffset != 0) {
1369
+ if (!bUTC && iTZOffset !== 0) {
1383
1370
  sTimeZone += bPositiveOffset ? '-' : '+';
1384
1371
  sTimeZone += String(iHourOffset).padStart(2, '0');
1385
1372
  if (oField.digits > 1 || iMinuteOffset > 0) {
@@ -1403,8 +1390,8 @@ DateFormat.prototype.oSymbols = {
1403
1390
  return oParseHelper.parseTZ(sValue, oPart.digits === 3 || oPart.digits === 5);
1404
1391
  }
1405
1392
  }
1406
- },
1407
- 'V': {
1393
+ }),
1394
+ 'V': DateFormat._createPatternSymbol({
1408
1395
  name: 'timezoneID',
1409
1396
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1410
1397
  if (!bUTC && oField.digits === 2) {
@@ -1444,7 +1431,7 @@ DateFormat.prototype.oSymbols = {
1444
1431
  }
1445
1432
  return oTimezoneParsed;
1446
1433
  }
1447
- }
1434
+ })
1448
1435
  };
1449
1436
  DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1450
1437
  if (this.oFormatOptions.relative) {
@@ -1532,7 +1519,7 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1532
1519
  vJSDate = convertToTimezone(vJSDate, sTimezone, bUTC);
1533
1520
  sResult = this._format(vJSDate, bUTC, sTimezone);
1534
1521
  }
1535
- if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1522
+ if (sCalendarType === CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1536
1523
  sResult = sResult.replace(/(^|[^\d])1年/g, '$1元年');
1537
1524
  }
1538
1525
  return sResult;
@@ -1598,21 +1585,28 @@ DateFormat.prototype._getGreatestDiffField = function (aDates) {
1598
1585
  return null;
1599
1586
  };
1600
1587
  DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict, sTimezone) {
1601
- var iIndex = 0, sFlexibleDayPeriod, oPart, bPM, sSubValue, oResult;
1602
- var oDateValue = {
1603
- valid: true,
1604
- lastTimezonePatternSymbol: ''
1605
- };
1606
- var oParseConf = {
1607
- formatArray: aFormatArray,
1608
- dateValue: oDateValue,
1609
- strict: bStrict
1610
- };
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
+ }
1611
1602
  for (var i = 0; i < aFormatArray.length; i++) {
1612
1603
  sSubValue = sValue.substr(iIndex);
1613
1604
  oPart = aFormatArray[i];
1605
+ oPrevPart = aFormatArray[i - 1];
1606
+ oNextPart = aFormatArray[i + 1];
1614
1607
  oParseConf.index = i;
1615
- 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) || {};
1616
1610
  if (oResult.tzDiff !== undefined || oResult.timezone) {
1617
1611
  oResult.lastTimezonePatternSymbol = oPart.symbol;
1618
1612
  }
@@ -1793,7 +1787,7 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1793
1787
  if (bStrict === undefined) {
1794
1788
  bStrict = this.oFormatOptions.strictParsing;
1795
1789
  }
1796
- if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1790
+ if (sCalendarType === CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1797
1791
  sValue = sValue.replace(/元年/g, '1年');
1798
1792
  }
1799
1793
  if (!this.oFormatOptions.interval) {
@@ -1830,7 +1824,7 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1830
1824
  } else {
1831
1825
  var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict, sTimezone);
1832
1826
  var oJSDate1, oJSDate2;
1833
- if (aDateValues && aDateValues.length == 2) {
1827
+ if (aDateValues && aDateValues.length === 2) {
1834
1828
  var oDateValue1 = mergeWithoutOverwrite(aDateValues[0], aDateValues[1]);
1835
1829
  var oDateValue2 = mergeWithoutOverwrite(aDateValues[1], aDateValues[0]);
1836
1830
  oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
@@ -1857,7 +1851,7 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1857
1851
  }
1858
1852
  }
1859
1853
  }
1860
- if (!this.bIsFallback) {
1854
+ if (this.aFallbackFormats) {
1861
1855
  var vDate;
1862
1856
  this.aFallbackFormats.every(function (oFallbackFormat) {
1863
1857
  vDate = oFallbackFormat.parse(sValue, bUTCInputParameter, bStrict);
@@ -1889,20 +1883,20 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1889
1883
  for (i = 0; i < sPattern.length; i++) {
1890
1884
  var sCurChar = sPattern.charAt(i), sNextChar, sPrevChar, sPrevPrevChar;
1891
1885
  if (bQuoted) {
1892
- if (sCurChar == '\'') {
1886
+ if (sCurChar === '\'') {
1893
1887
  sPrevChar = sPattern.charAt(i - 1);
1894
1888
  sPrevPrevChar = sPattern.charAt(i - 2);
1895
1889
  sNextChar = sPattern.charAt(i + 1);
1896
- if (sPrevChar == '\'' && sPrevPrevChar != '\'') {
1890
+ if (sPrevChar === '\'' && sPrevPrevChar !== '\'') {
1897
1891
  bQuoted = false;
1898
- } else if (sNextChar == '\'') {
1892
+ } else if (sNextChar === '\'') {
1899
1893
  i += 1;
1900
1894
  } else {
1901
1895
  bQuoted = false;
1902
1896
  continue;
1903
1897
  }
1904
1898
  }
1905
- if (sState == 'text') {
1899
+ if (sState === 'text') {
1906
1900
  oCurrentObject.value += sCurChar;
1907
1901
  } else {
1908
1902
  oCurrentObject = {
@@ -1913,11 +1907,11 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1913
1907
  sState = 'text';
1914
1908
  }
1915
1909
  } else {
1916
- if (sCurChar == '\'') {
1910
+ if (sCurChar === '\'') {
1917
1911
  bQuoted = true;
1918
1912
  } else if (this.oSymbols[sCurChar]) {
1919
1913
  sNewState = this.oSymbols[sCurChar].name;
1920
- if (sState == sNewState) {
1914
+ if (sState === sNewState) {
1921
1915
  oCurrentObject.digits++;
1922
1916
  } else {
1923
1917
  oCurrentObject = {
@@ -1937,7 +1931,7 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1937
1931
  }
1938
1932
  }
1939
1933
  } else {
1940
- if (sState == 'text') {
1934
+ if (sState === 'text') {
1941
1935
  oCurrentObject.value += sCurChar;
1942
1936
  } else {
1943
1937
  oCurrentObject = {
@@ -1973,57 +1967,78 @@ DateFormat.prototype.parseRelative = function (sValue, bUTC) {
1973
1967
  }
1974
1968
  }
1975
1969
  function computeRelativeDate(iDiff, sScale) {
1976
- var iToday, oToday = new Date(), oJSDate;
1970
+ var oResult = UI5Date.getInstance();
1977
1971
  if (bUTC) {
1978
- iToday = oToday.getTime();
1979
- } else {
1980
- iToday = Date.UTC(oToday.getFullYear(), oToday.getMonth(), oToday.getDate(), oToday.getHours(), oToday.getMinutes(), oToday.getSeconds(), oToday.getMilliseconds());
1981
- }
1982
- oJSDate = new Date(iToday);
1983
- switch (sScale) {
1984
- case 'second':
1985
- oJSDate.setUTCSeconds(oJSDate.getUTCSeconds() + iDiff);
1986
- break;
1987
- case 'minute':
1988
- oJSDate.setUTCMinutes(oJSDate.getUTCMinutes() + iDiff);
1989
- break;
1990
- case 'hour':
1991
- oJSDate.setUTCHours(oJSDate.getUTCHours() + iDiff);
1992
- break;
1993
- case 'day':
1994
- oJSDate.setUTCDate(oJSDate.getUTCDate() + iDiff);
1995
- break;
1996
- case 'week':
1997
- oJSDate.setUTCDate(oJSDate.getUTCDate() + iDiff * 7);
1998
- break;
1999
- case 'month':
2000
- oJSDate.setUTCMonth(oJSDate.getUTCMonth() + iDiff);
2001
- break;
2002
- case 'quarter':
2003
- oJSDate.setUTCMonth(oJSDate.getUTCMonth() + iDiff * 3);
2004
- break;
2005
- case 'year':
2006
- oJSDate.setUTCFullYear(oJSDate.getUTCFullYear() + iDiff);
2007
- break;
2008
- }
2009
- if (bUTC) {
2010
- 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
+ }
2011
2000
  } else {
2012
- 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
+ }
2013
2027
  }
2028
+ return oResult;
2014
2029
  }
2015
2030
  };
2016
2031
  DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange, sTimezone) {
2017
- 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';
2018
2033
  iDiffSeconds = (oJSDate.getTime() - oToday.getTime()) / 1000;
2019
- if (this.oFormatOptions.relativeScale == 'auto') {
2034
+ if (this.oFormatOptions.relativeScale === 'auto') {
2020
2035
  sScale = this._getScale(iDiffSeconds, this.aRelativeScales);
2021
2036
  sScale = fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds);
2022
2037
  }
2023
2038
  if (!aRange) {
2024
2039
  aRange = this._mRanges[sScale];
2025
2040
  }
2026
- if (sScale == 'year' || sScale == 'month' || sScale == 'day') {
2041
+ if (sScale === 'year' || sScale === 'month' || sScale === 'day') {
2027
2042
  oToday = new Date(Date.UTC(oToday.getUTCFullYear(), oToday.getUTCMonth(), oToday.getUTCDate()));
2028
2043
  oDateUTC = new Date(0);
2029
2044
  oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
@@ -2033,7 +2048,7 @@ DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange, sTimezone
2033
2048
  oToday,
2034
2049
  oJSDate
2035
2050
  ]);
2036
- if (this.oFormatOptions.relativeScale != 'auto' && (iDiff < aRange[0] || iDiff > aRange[1])) {
2051
+ if (this.oFormatOptions.relativeScale !== 'auto' && (iDiff < aRange[0] || iDiff > aRange[1])) {
2037
2052
  return null;
2038
2053
  }
2039
2054
  sPattern = this.oLocaleData.getRelativePattern(sScale, iDiff, iDiffSeconds > 0, this.oFormatOptions.relativeStyle);
@@ -2110,7 +2125,7 @@ function fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds) {
2110
2125
  return sScale;
2111
2126
  }
2112
2127
  function cutDateFields(oDate, iStartIndex) {
2113
- var aFields = [
2128
+ var sMethodName, aFields = [
2114
2129
  'FullYear',
2115
2130
  'Month',
2116
2131
  'Date',
@@ -2118,8 +2133,7 @@ function cutDateFields(oDate, iStartIndex) {
2118
2133
  'Minutes',
2119
2134
  'Seconds',
2120
2135
  'Milliseconds'
2121
- ], sMethodName;
2122
- var oDateCopy = new Date(oDate.getTime());
2136
+ ], oDateCopy = new Date(oDate.getTime());
2123
2137
  for (var i = iStartIndex; i < aFields.length; i++) {
2124
2138
  sMethodName = 'setUTC' + aFields[iStartIndex];
2125
2139
  oDateCopy[sMethodName].apply(oDateCopy, [0]);