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

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 (199) hide show
  1. package/.eslintignore +1 -1
  2. package/.npsrc.json +3 -0
  3. package/CHANGELOG.md +343 -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 +14 -0
  44. package/dist/dates/modifyDateBy.js +42 -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 +5531 -5906
  60. package/dist/generated/assets/cldr/ar_EG.json +5531 -5906
  61. package/dist/generated/assets/cldr/ar_SA.json +5530 -5906
  62. package/dist/generated/assets/cldr/bg.json +4452 -4979
  63. package/dist/generated/assets/cldr/ca.json +4440 -4996
  64. package/dist/generated/assets/cldr/cs.json +4960 -5498
  65. package/dist/generated/assets/cldr/cy.json +5211 -5884
  66. package/dist/generated/assets/cldr/da.json +4308 -4888
  67. package/dist/generated/assets/cldr/de.json +4313 -4916
  68. package/dist/generated/assets/cldr/de_AT.json +4314 -4917
  69. package/dist/generated/assets/cldr/de_CH.json +4312 -4915
  70. package/dist/generated/assets/cldr/el.json +4281 -4883
  71. package/dist/generated/assets/cldr/el_CY.json +4281 -4883
  72. package/dist/generated/assets/cldr/en.json +4316 -4971
  73. package/dist/generated/assets/cldr/en_AU.json +4319 -4962
  74. package/dist/generated/assets/cldr/en_GB.json +4329 -4971
  75. package/dist/generated/assets/cldr/en_HK.json +4337 -4977
  76. package/dist/generated/assets/cldr/en_IE.json +4328 -4971
  77. package/dist/generated/assets/cldr/en_IN.json +4333 -4972
  78. package/dist/generated/assets/cldr/en_NZ.json +4328 -4971
  79. package/dist/generated/assets/cldr/en_PG.json +4329 -4972
  80. package/dist/generated/assets/cldr/en_SG.json +4333 -4973
  81. package/dist/generated/assets/cldr/en_ZA.json +4329 -4972
  82. package/dist/generated/assets/cldr/es.json +4331 -4912
  83. package/dist/generated/assets/cldr/es_AR.json +4334 -4914
  84. package/dist/generated/assets/cldr/es_BO.json +4333 -4913
  85. package/dist/generated/assets/cldr/es_CL.json +4334 -4914
  86. package/dist/generated/assets/cldr/es_CO.json +4333 -4913
  87. package/dist/generated/assets/cldr/es_MX.json +4335 -4915
  88. package/dist/generated/assets/cldr/es_PE.json +4333 -4913
  89. package/dist/generated/assets/cldr/es_UY.json +4335 -4915
  90. package/dist/generated/assets/cldr/es_VE.json +4334 -4914
  91. package/dist/generated/assets/cldr/et.json +4340 -4967
  92. package/dist/generated/assets/cldr/fa.json +4367 -4883
  93. package/dist/generated/assets/cldr/fi.json +4463 -5008
  94. package/dist/generated/assets/cldr/fr.json +4357 -4979
  95. package/dist/generated/assets/cldr/fr_BE.json +4357 -4979
  96. package/dist/generated/assets/cldr/fr_CA.json +4351 -4973
  97. package/dist/generated/assets/cldr/fr_CH.json +4375 -4997
  98. package/dist/generated/assets/cldr/fr_LU.json +4357 -4979
  99. package/dist/generated/assets/cldr/he.json +4869 -5378
  100. package/dist/generated/assets/cldr/hi.json +4295 -4829
  101. package/dist/generated/assets/cldr/hr.json +4583 -4919
  102. package/dist/generated/assets/cldr/hu.json +4364 -4856
  103. package/dist/generated/assets/cldr/id.json +4060 -4658
  104. package/dist/generated/assets/cldr/it.json +4299 -4950
  105. package/dist/generated/assets/cldr/it_CH.json +4299 -4950
  106. package/dist/generated/assets/cldr/ja.json +4211 -4830
  107. package/dist/generated/assets/cldr/kk.json +4339 -4725
  108. package/dist/generated/assets/cldr/ko.json +4189 -4738
  109. package/dist/generated/assets/cldr/lt.json +4850 -5481
  110. package/dist/generated/assets/cldr/lv.json +4587 -5112
  111. package/dist/generated/assets/cldr/ms.json +4021 -4515
  112. package/dist/generated/assets/cldr/nb.json +4335 -4977
  113. package/dist/generated/assets/cldr/nl.json +4294 -4884
  114. package/dist/generated/assets/cldr/nl_BE.json +4294 -4884
  115. package/dist/generated/assets/cldr/pl.json +4667 -5176
  116. package/dist/generated/assets/cldr/pt.json +4235 -4805
  117. package/dist/generated/assets/cldr/pt_PT.json +4372 -4940
  118. package/dist/generated/assets/cldr/ro.json +4563 -5090
  119. package/dist/generated/assets/cldr/ru.json +4909 -5407
  120. package/dist/generated/assets/cldr/ru_UA.json +4909 -5407
  121. package/dist/generated/assets/cldr/sk.json +4939 -5370
  122. package/dist/generated/assets/cldr/sl.json +4910 -5340
  123. package/dist/generated/assets/cldr/sr.json +4585 -5126
  124. package/dist/generated/assets/cldr/sr_Latn.json +4574 -5127
  125. package/dist/generated/assets/cldr/sv.json +4362 -5011
  126. package/dist/generated/assets/cldr/th.json +4214 -4797
  127. package/dist/generated/assets/cldr/tr.json +4400 -4979
  128. package/dist/generated/assets/cldr/uk.json +4858 -5353
  129. package/dist/generated/assets/cldr/vi.json +4070 -4673
  130. package/dist/generated/assets/cldr/zh_CN.json +4100 -4632
  131. package/dist/generated/assets/cldr/zh_HK.json +4108 -4640
  132. package/dist/generated/assets/cldr/zh_SG.json +4108 -4640
  133. package/dist/generated/assets/cldr/zh_TW.json +4131 -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/i18n/LanguageTag.js +35 -0
  143. package/dist/sap/base/i18n/Localization.d.ts +4 -0
  144. package/dist/sap/base/i18n/Localization.js +12 -0
  145. package/dist/sap/base/i18n/Localization.js.map +1 -0
  146. package/dist/sap/base/i18n/date/CalendarType.js +8 -0
  147. package/dist/sap/base/i18n/date/CalendarWeekNumbering.js +30 -0
  148. package/dist/sap/base/i18n/date/TimezoneUtils.js +89 -0
  149. package/dist/sap/base/util/LoaderExtensions.d.ts +4 -0
  150. package/dist/sap/base/util/LoaderExtensions.js +9 -12
  151. package/dist/sap/base/util/LoaderExtensions.js.map +1 -0
  152. package/dist/sap/ui/base/Metadata.js +20 -9
  153. package/dist/sap/ui/core/CalendarType.js +2 -8
  154. package/dist/sap/ui/core/Configuration.d.ts +17 -0
  155. package/dist/sap/ui/core/Configuration.js +21 -0
  156. package/dist/sap/ui/core/Configuration.js.map +1 -0
  157. package/dist/sap/ui/core/Core.d.ts +26 -0
  158. package/dist/sap/ui/core/Core.js +7 -34
  159. package/dist/sap/ui/core/Core.js.map +1 -0
  160. package/dist/sap/ui/core/FormatSettings.d.ts +10 -0
  161. package/dist/sap/ui/core/FormatSettings.js +14 -0
  162. package/dist/sap/ui/core/FormatSettings.js.map +1 -0
  163. package/dist/sap/ui/core/Locale.js +28 -122
  164. package/dist/sap/ui/core/LocaleData.js +185 -38
  165. package/dist/sap/ui/core/date/Buddhist.js +0 -6
  166. package/dist/sap/ui/core/date/CalendarUtils.js +25 -0
  167. package/dist/sap/ui/core/date/CalendarWeekNumbering.js +2 -0
  168. package/dist/sap/ui/core/date/Islamic.js +3 -3
  169. package/dist/sap/ui/core/date/Japanese.js +4 -4
  170. package/dist/sap/ui/core/date/UI5Date.js +305 -0
  171. package/dist/sap/ui/core/date/UniversalDate.js +68 -27
  172. package/dist/sap/ui/core/format/DateFormat.js +539 -383
  173. package/dist/sap/ui/core/format/TimezoneUtil.js +2 -83
  174. package/{package-scripts.js → package-scripts.cjs} +7 -5
  175. package/package.json +7 -5
  176. package/tsconfig.json +14 -0
  177. package/used-modules.txt +8 -1
  178. package/src/Assets.js +0 -2
  179. package/src/DateFormat.js +0 -3
  180. package/src/LocaleData.js +0 -3
  181. package/src/dates/CalendarDate.js +0 -229
  182. package/src/dates/ExtremeDates.js +0 -39
  183. package/src/dates/calculateWeekNumber.js +0 -51
  184. package/src/dates/convertMonthNumbersToMonthNames.js +0 -33
  185. package/src/dates/getDaysInMonth.js +0 -11
  186. package/src/dates/getRoundedTimestamp.js +0 -14
  187. package/src/dates/getTodayUTCTimestamp.js +0 -9
  188. package/src/dates/modifyDateBy.js +0 -42
  189. package/src/dates/transformDateToSecondaryType.js +0 -20
  190. package/src/getCachedLocaleDataInstance.js +0 -13
  191. package/src/locale/getLocaleData.js +0 -27
  192. package/src/sap/base/util/LoaderExtensions.js +0 -17
  193. package/src/sap/ui/core/Core.js +0 -40
  194. /package/{config/.eslintrc.js → .eslintrc.cjs} +0 -0
  195. /package/{src/features/calendar/Buddhist.js → dist/features/calendar/Buddhist.d.ts} +0 -0
  196. /package/{src/features/calendar/Gregorian.js → dist/features/calendar/Gregorian.d.ts} +0 -0
  197. /package/{src/features/calendar/Islamic.js → dist/features/calendar/Islamic.d.ts} +0 -0
  198. /package/{src/features/calendar/Japanese.js → dist/features/calendar/Japanese.d.ts} +0 -0
  199. /package/{src/features/calendar/Persian.js → dist/features/calendar/Persian.d.ts} +0 -0
@@ -1,13 +1,17 @@
1
- import Core from '../Core.js';
1
+ import Log from '../../../base/Log.js';
2
+ import formatMessage from '../../../base/strings/formatMessage.js';
3
+ import deepEqual from '../../../base/util/deepEqual.js';
4
+ import extend from '../../../base/util/extend.js';
2
5
  import CalendarType from '../CalendarType.js';
6
+ import Configuration from '../Configuration.js';
7
+ import Core from '../Core.js';
3
8
  import Locale from '../Locale.js';
4
9
  import LocaleData from '../LocaleData.js';
10
+ import CalendarUtils from '../date/CalendarUtils.js';
11
+ import CalendarWeekNumbering from '../date/CalendarWeekNumbering.js';
12
+ import UI5Date from '../date/UI5Date.js';
5
13
  import UniversalDate from '../date/UniversalDate.js';
6
14
  import TimezoneUtil from './TimezoneUtil.js';
7
- import deepEqual from '../../../base/util/deepEqual.js';
8
- import formatMessage from '../../../base/strings/formatMessage.js';
9
- import Log from '../../../base/Log.js';
10
- import extend from '../../../base/util/extend.js';
11
15
  var DateFormat = function () {
12
16
  throw new Error();
13
17
  };
@@ -229,21 +233,23 @@ DateFormat.getDateTimeInstance = function (oFormatOptions, oLocale) {
229
233
  };
230
234
  DateFormat.getDateTimeWithTimezoneInstance = function (oFormatOptions, oLocale) {
231
235
  if (oFormatOptions && !(oFormatOptions instanceof Locale)) {
232
- oFormatOptions = Object.assign({}, oFormatOptions);
233
- if (typeof oFormatOptions.showTimezone === 'string') {
234
- var sShowTimezone = oFormatOptions.showTimezone;
235
- if (oFormatOptions.showDate === undefined && oFormatOptions.showTime === undefined) {
236
- if (sShowTimezone === 'Hide') {
237
- oFormatOptions.showTimezone = false;
238
- } else if (sShowTimezone === 'Only') {
239
- oFormatOptions.showDate = false;
240
- oFormatOptions.showTime = false;
236
+ (function () {
237
+ oFormatOptions = Object.assign({}, oFormatOptions);
238
+ if (typeof oFormatOptions.showTimezone === 'string') {
239
+ var sShowTimezone = oFormatOptions.showTimezone;
240
+ if (oFormatOptions.showDate === undefined && oFormatOptions.showTime === undefined) {
241
+ if (sShowTimezone === 'Hide') {
242
+ oFormatOptions.showTimezone = false;
243
+ } else if (sShowTimezone === 'Only') {
244
+ oFormatOptions.showDate = false;
245
+ oFormatOptions.showTime = false;
246
+ }
241
247
  }
248
+ oFormatOptions.showTimezone = sShowTimezone !== 'Hide';
242
249
  }
243
- oFormatOptions.showTimezone = sShowTimezone !== 'Hide';
244
- }
250
+ }());
245
251
  if (oFormatOptions.showDate === false && oFormatOptions.showTime === false && oFormatOptions.showTimezone === false) {
246
- throw new TypeError('Invalid Configuration. One of the following format options must be true: showDate, showTime or showTimezone.');
252
+ throw new TypeError('Invalid Configuration. One of the following format options must be true: ' + 'showDate, showTime or showTimezone.');
247
253
  }
248
254
  }
249
255
  return this.createInstance(oFormatOptions, oLocale, DateFormat._getDateTimeWithTimezoneInfo(oFormatOptions || {}));
@@ -256,14 +262,15 @@ function createIntervalPatternWithNormalConnector(oFormat) {
256
262
  sPattern = sPattern.replace(/[^\{\}01 ]/, '-');
257
263
  return sPattern.replace(/\{(0|1)\}/g, oFormat.oFormatOptions.pattern);
258
264
  }
259
- DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
260
- var oFormat = Object.create(this.prototype);
265
+ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo, bIsFallback) {
266
+ var aFallbackFormatOptions, oFormat, sPattern;
267
+ oFormat = Object.create(this.prototype);
261
268
  if (oFormatOptions instanceof Locale) {
262
269
  oLocale = oFormatOptions;
263
270
  oFormatOptions = undefined;
264
271
  }
265
272
  if (!oLocale) {
266
- oLocale = Core.getConfiguration().getFormatSettings().getFormatLocale();
273
+ oLocale = Configuration.getFormatSettings().getFormatLocale();
267
274
  }
268
275
  oFormat.oLocale = oLocale;
269
276
  oFormat.oLocaleData = LocaleData.getInstance(oLocale);
@@ -279,7 +286,13 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
279
286
  }
280
287
  oFormat.type = oInfo.type;
281
288
  if (!oFormat.oFormatOptions.calendarType) {
282
- oFormat.oFormatOptions.calendarType = Core.getConfiguration().getCalendarType();
289
+ oFormat.oFormatOptions.calendarType = Configuration.getCalendarType();
290
+ }
291
+ if (oFormat.oFormatOptions.firstDayOfWeek === undefined && oFormat.oFormatOptions.minimalDaysInFirstWeek !== undefined || oFormat.oFormatOptions.firstDayOfWeek !== undefined && oFormat.oFormatOptions.minimalDaysInFirstWeek === undefined) {
292
+ throw new TypeError('Format options firstDayOfWeek and minimalDaysInFirstWeek need both to be set, but only one was provided.');
293
+ }
294
+ if (oFormat.oFormatOptions.calendarWeekNumbering && !Object.values(CalendarWeekNumbering).includes(oFormat.oFormatOptions.calendarWeekNumbering)) {
295
+ throw new TypeError('Illegal format option calendarWeekNumbering: \'' + oFormat.oFormatOptions.calendarWeekNumbering + '\'');
283
296
  }
284
297
  if (!oFormat.oFormatOptions.pattern) {
285
298
  if (oFormat.oFormatOptions.format) {
@@ -289,13 +302,16 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
289
302
  }
290
303
  }
291
304
  if (oFormat.oFormatOptions.interval) {
305
+ var sSinglePattern, sDelimiter = oFormat.oFormatOptions.intervalDelimiter;
292
306
  if (oFormat.oFormatOptions.format) {
293
307
  oFormat.intervalPatterns = oFormat.oLocaleData.getCustomIntervalPattern(oFormat.oFormatOptions.format, null, oFormat.oFormatOptions.calendarType);
294
308
  if (typeof oFormat.intervalPatterns === 'string') {
295
309
  oFormat.intervalPatterns = [oFormat.intervalPatterns];
296
310
  }
297
- oFormat.intervalPatterns.push(oFormat.oLocaleData.getCustomDateTimePattern(oFormat.oFormatOptions.format, oFormat.oFormatOptions.calendarType));
311
+ sSinglePattern = oFormat.oLocaleData.getCustomDateTimePattern(oFormat.oFormatOptions.format, oFormat.oFormatOptions.calendarType);
312
+ oFormat.intervalPatterns.push(sSinglePattern);
298
313
  } else {
314
+ sSinglePattern = oFormat.oFormatOptions.pattern;
299
315
  oFormat.intervalPatterns = [
300
316
  oFormat.oLocaleData.getCombinedIntervalPattern(oFormat.oFormatOptions.pattern, oFormat.oFormatOptions.calendarType),
301
317
  oFormat.oFormatOptions.pattern
@@ -303,31 +319,34 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
303
319
  }
304
320
  var sCommonConnectorPattern = createIntervalPatternWithNormalConnector(oFormat);
305
321
  oFormat.intervalPatterns.push(sCommonConnectorPattern);
322
+ if (sDelimiter) {
323
+ sDelimiter = sDelimiter.replace(/'/g, '\'\'');
324
+ sDelimiter = '\'' + sDelimiter + '\'';
325
+ oFormat.intervalPatterns.unshift(sSinglePattern + sDelimiter + sSinglePattern);
326
+ }
327
+ oFormat.intervalPatterns = Array.from(new Set(oFormat.intervalPatterns));
306
328
  }
307
- if (!oFormat.oFormatOptions.fallback) {
308
- if (!oInfo.oFallbackFormats) {
309
- oInfo.oFallbackFormats = {};
329
+ if (!bIsFallback) {
330
+ aFallbackFormatOptions = oInfo.aFallbackFormatOptions;
331
+ if (oInfo.bShortFallbackFormatOptions) {
332
+ sPattern = oInfo.getPattern(oFormat.oLocaleData, 'short');
333
+ aFallbackFormatOptions = aFallbackFormatOptions.concat(DateFormat._createFallbackOptionsWithoutDelimiter(sPattern));
310
334
  }
311
- var sLocale = oLocale.toString(), sCalendarType = oFormat.oFormatOptions.calendarType, sKey = sLocale + '-' + sCalendarType, sPattern, aFallbackFormatOptions;
312
335
  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;
336
+ aFallbackFormatOptions = DateFormat._createFallbackOptionsWithoutDelimiter(oFormat.oFormatOptions.pattern).concat(aFallbackFormatOptions);
337
+ }
338
+ aFallbackFormatOptions = aFallbackFormatOptions.reduce(function (aFallbacks, oOptions) {
339
+ var aKeys = Object.keys(oOptions), bDuplicate = aFallbacks.some(function (oOptions0) {
340
+ return Object.keys(oOptions0).length === aKeys.length && aKeys.every(function (sKey) {
341
+ return oOptions0[sKey] === oOptions[sKey];
342
+ });
343
+ });
344
+ if (!bDuplicate) {
345
+ aFallbacks.push(oOptions);
346
+ }
347
+ return aFallbacks;
348
+ }, []);
349
+ oFormat.aFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, oFormat.oFormatOptions.calendarType, oLocale, oInfo, oFormat.oFormatOptions);
331
350
  }
332
351
  oFormat.oRequiredParts = oInfo.oRequiredParts;
333
352
  oFormat.aRelativeScales = oInfo.aRelativeScales;
@@ -361,7 +380,15 @@ DateFormat.prototype.init = function () {
361
380
  this.aErasNarrow = this.oLocaleData.getEras('narrow', sCalendarType);
362
381
  this.aErasAbbrev = this.oLocaleData.getEras('abbreviated', sCalendarType);
363
382
  this.aErasWide = this.oLocaleData.getEras('wide', sCalendarType);
364
- this.aDayPeriods = this.oLocaleData.getDayPeriods('abbreviated', sCalendarType);
383
+ this.aDayPeriodsAbbrev = this.oLocaleData.getDayPeriods('abbreviated', sCalendarType);
384
+ this.aDayPeriodsNarrow = this.oLocaleData.getDayPeriods('narrow', sCalendarType);
385
+ this.aDayPeriodsWide = this.oLocaleData.getDayPeriods('wide', sCalendarType);
386
+ this.oFlexibleDayPeriodsAbbrev = this.oLocaleData.getFlexibleDayPeriods('abbreviated', sCalendarType);
387
+ this.oFlexibleDayPeriodsNarrow = this.oLocaleData.getFlexibleDayPeriods('narrow', sCalendarType);
388
+ this.oFlexibleDayPeriodsWide = this.oLocaleData.getFlexibleDayPeriods('wide', sCalendarType);
389
+ this.oFlexibleDayPeriodsAbbrevSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('abbreviated', sCalendarType);
390
+ this.oFlexibleDayPeriodsNarrowSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('narrow', sCalendarType);
391
+ this.oFlexibleDayPeriodsWideSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('wide', sCalendarType);
365
392
  this.aFormatArray = this.parseCldrDatePattern(this.oFormatOptions.pattern);
366
393
  this.sAllowedCharacters = this.getAllowedCharacters(this.aFormatArray);
367
394
  };
@@ -378,10 +405,7 @@ DateFormat._createFallbackFormat = function (aFallbackFormatOptions, sCalendarTy
378
405
  oFormatOptions.interval = true;
379
406
  }
380
407
  oFormatOptions.calendarType = sCalendarType;
381
- oFormatOptions.fallback = true;
382
- var oFallbackFormat = DateFormat.createInstance(oFormatOptions, oLocale, oInfo);
383
- oFallbackFormat.bIsFallback = true;
384
- return oFallbackFormat;
408
+ return DateFormat.createInstance(oFormatOptions, oLocale, oInfo, true);
385
409
  });
386
410
  };
387
411
  DateFormat._createFallbackOptionsWithoutDelimiter = function (sBasePattern) {
@@ -417,9 +441,6 @@ var oParseHelper = {
417
441
  while (iLength < iMaxLength && this.isNumber(sValue.charCodeAt(iLength))) {
418
442
  iLength++;
419
443
  }
420
- if (typeof sValue !== 'string') {
421
- sValue = sValue.toString();
422
- }
423
444
  return sValue.substr(0, iLength);
424
445
  },
425
446
  startsWithIgnoreCase: function (sValue, sSubstring, sLocale) {
@@ -452,7 +473,7 @@ var oParseHelper = {
452
473
  },
453
474
  parseTZ: function (sValue, bColonSeparated) {
454
475
  var iLength = 0;
455
- var iTZFactor = sValue.charAt(0) == '+' ? -1 : 1;
476
+ var iTZFactor = sValue.charAt(0) === '+' ? -1 : 1;
456
477
  var sPart;
457
478
  iLength++;
458
479
  sPart = this.findNumbers(sValue.substr(iLength), 2);
@@ -472,14 +493,30 @@ var oParseHelper = {
472
493
  tzDiff: (iTZDiff + 60 * iTZDiffHour) * 60 * iTZFactor
473
494
  };
474
495
  },
475
- checkValid: function (sType, bPartInvalid, oFormat) {
476
- if (sType in oFormat.oRequiredParts && bPartInvalid) {
496
+ checkValid: function (sSymbolName, bPartInvalid, oFormat) {
497
+ if (sSymbolName in oFormat.oRequiredParts && bPartInvalid) {
477
498
  return false;
478
499
  }
500
+ return true;
479
501
  }
480
502
  };
503
+ DateFormat._createPatternSymbol = function (mParameters) {
504
+ var fnIsNumeric = typeof mParameters.isNumeric === 'function' && mParameters.isNumeric || function () {
505
+ return mParameters.isNumeric || false;
506
+ };
507
+ return {
508
+ name: mParameters.name,
509
+ format: mParameters.format || function () {
510
+ return '';
511
+ },
512
+ parse: mParameters.parse || function () {
513
+ return {};
514
+ },
515
+ isNumeric: fnIsNumeric
516
+ };
517
+ };
481
518
  DateFormat.prototype.oSymbols = {
482
- '': {
519
+ '': DateFormat._createPatternSymbol({
483
520
  name: 'text',
484
521
  format: function (oField, oDate) {
485
522
  return oField.value;
@@ -521,8 +558,8 @@ DateFormat.prototype.oSymbols = {
521
558
  return { valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat) };
522
559
  }
523
560
  }
524
- },
525
- 'G': {
561
+ }),
562
+ 'G': DateFormat._createPatternSymbol({
526
563
  name: 'era',
527
564
  format: function (oField, oDate, bUTC, oFormat) {
528
565
  var iEra = oDate.getUTCEra();
@@ -555,34 +592,35 @@ DateFormat.prototype.oSymbols = {
555
592
  valid: oParseHelper.checkValid(oPart.type, true, oFormat)
556
593
  };
557
594
  }
558
- },
559
- 'y': {
595
+ }),
596
+ 'y': DateFormat._createPatternSymbol({
560
597
  name: 'year',
561
598
  format: function (oField, oDate, bUTC, oFormat) {
562
599
  var iYear = oDate.getUTCFullYear();
563
600
  var sYear = String(iYear);
564
601
  var sCalendarType = oFormat.oFormatOptions.calendarType;
565
- if (oField.digits == 2 && sYear.length > 2) {
602
+ if (oField.digits === 2 && sYear.length > 2) {
566
603
  sYear = sYear.substr(sYear.length - 2);
567
604
  }
568
- if (sCalendarType != CalendarType.Japanese && oField.digits == 1 && iYear < 100) {
605
+ if (sCalendarType !== CalendarType.Japanese && oField.digits === 1 && iYear < 100) {
569
606
  sYear = sYear.padStart(4, '0');
570
607
  }
571
608
  return sYear.padStart(oField.digits, '0');
572
609
  },
573
610
  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);
611
+ var iExpectedDigits, sPart, bPartInvalid, sCalendarType = oFormat.oFormatOptions.calendarType;
612
+ if (oPart.digits === 1) {
613
+ iExpectedDigits = 4;
614
+ } else if (oPart.digits === 2) {
615
+ iExpectedDigits = 2;
580
616
  } else {
581
- sPart = oParseHelper.findNumbers(sValue, oPart.digits);
617
+ iExpectedDigits = oPart.digits;
582
618
  }
619
+ sPart = oParseHelper.findNumbers(sValue, iExpectedDigits);
620
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length !== iExpectedDigits;
583
621
  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;
622
+ if (sCalendarType !== CalendarType.Japanese && sPart.length <= 2) {
623
+ var oCurrentDate = UniversalDate.getInstance(UI5Date.getInstance(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iYear - iCurrentYear;
586
624
  if (iYearDiff < -70) {
587
625
  iYear += (iCurrentCentury + 1) * 100;
588
626
  } else if (iYearDiff < 30) {
@@ -593,40 +631,42 @@ DateFormat.prototype.oSymbols = {
593
631
  }
594
632
  return {
595
633
  length: sPart.length,
596
- valid: oParseHelper.checkValid(oPart.type, sPart === '', oFormat),
634
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat),
597
635
  year: iYear
598
636
  };
599
- }
600
- },
601
- 'Y': {
637
+ },
638
+ isNumeric: true
639
+ }),
640
+ 'Y': DateFormat._createPatternSymbol({
602
641
  name: 'weekYear',
603
642
  format: function (oField, oDate, bUTC, oFormat) {
604
- var oWeek = oDate.getUTCWeek();
643
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
605
644
  var iWeekYear = oWeek.year;
606
645
  var sWeekYear = String(iWeekYear);
607
646
  var sCalendarType = oFormat.oFormatOptions.calendarType;
608
- if (oField.digits == 2 && sWeekYear.length > 2) {
647
+ if (oField.digits === 2 && sWeekYear.length > 2) {
609
648
  sWeekYear = sWeekYear.substr(sWeekYear.length - 2);
610
649
  }
611
- if (sCalendarType != CalendarType.Japanese && oField.digits == 1 && iWeekYear < 100) {
650
+ if (sCalendarType !== CalendarType.Japanese && oField.digits === 1 && iWeekYear < 100) {
612
651
  sWeekYear = sWeekYear.padStart(4, '0');
613
652
  }
614
653
  return sWeekYear.padStart(oField.digits, '0');
615
654
  },
616
655
  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);
656
+ var iExpectedDigits, sPart, bPartInvalid, sCalendarType = oFormat.oFormatOptions.calendarType;
657
+ if (oPart.digits === 1) {
658
+ iExpectedDigits = 4;
659
+ } else if (oPart.digits === 2) {
660
+ iExpectedDigits = 2;
623
661
  } else {
624
- sPart = oParseHelper.findNumbers(sValue, oPart.digits);
662
+ iExpectedDigits = oPart.digits;
625
663
  }
664
+ sPart = oParseHelper.findNumbers(sValue, iExpectedDigits);
665
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length !== iExpectedDigits;
626
666
  var iYear = parseInt(sPart);
627
667
  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;
668
+ if (sCalendarType !== CalendarType.Japanese && sPart.length <= 2) {
669
+ var oCurrentDate = UniversalDate.getInstance(UI5Date.getInstance(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iWeekYear - iCurrentYear;
630
670
  if (iYearDiff < -70) {
631
671
  iWeekYear += (iCurrentCentury + 1) * 100;
632
672
  } else if (iYearDiff < 30) {
@@ -637,19 +677,20 @@ DateFormat.prototype.oSymbols = {
637
677
  }
638
678
  return {
639
679
  length: sPart.length,
640
- valid: oParseHelper.checkValid(oPart.type, sPart === '', oFormat),
680
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat),
641
681
  year: iYear,
642
682
  weekYear: iWeekYear
643
683
  };
644
- }
645
- },
646
- 'M': {
684
+ },
685
+ isNumeric: true
686
+ }),
687
+ 'M': DateFormat._createPatternSymbol({
647
688
  name: 'month',
648
689
  format: function (oField, oDate, bUTC, oFormat) {
649
690
  var iMonth = oDate.getUTCMonth();
650
- if (oField.digits == 3) {
691
+ if (oField.digits === 3) {
651
692
  return oFormat.aMonthsAbbrev[iMonth];
652
- } else if (oField.digits == 4) {
693
+ } else if (oField.digits === 4) {
653
694
  return oFormat.aMonthsWide[iMonth];
654
695
  } else if (oField.digits > 4) {
655
696
  return oFormat.aMonthsNarrow[iMonth];
@@ -658,20 +699,18 @@ DateFormat.prototype.oSymbols = {
658
699
  }
659
700
  },
660
701
  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;
702
+ var iMonth, sPart, bPartInvalid, bValid, aMonthsVariants = [
703
+ oFormat.aMonthsWide,
704
+ oFormat.aMonthsWideSt,
705
+ oFormat.aMonthsAbbrev,
706
+ oFormat.aMonthsAbbrevSt,
707
+ oFormat.aMonthsNarrow,
708
+ oFormat.aMonthsNarrowSt
709
+ ];
672
710
  if (oPart.digits < 3) {
673
711
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
674
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
712
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
713
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
675
714
  iMonth = parseInt(sPart) - 1;
676
715
  if (oConfig.strict && (iMonth > 11 || iMonth < 0)) {
677
716
  bValid = false;
@@ -694,15 +733,18 @@ DateFormat.prototype.oSymbols = {
694
733
  length: sPart ? sPart.length : 0,
695
734
  valid: bValid
696
735
  };
736
+ },
737
+ isNumeric: function (iDigits) {
738
+ return iDigits < 3;
697
739
  }
698
- },
699
- 'L': {
740
+ }),
741
+ 'L': DateFormat._createPatternSymbol({
700
742
  name: 'monthStandalone',
701
743
  format: function (oField, oDate, bUTC, oFormat) {
702
744
  var iMonth = oDate.getUTCMonth();
703
- if (oField.digits == 3) {
745
+ if (oField.digits === 3) {
704
746
  return oFormat.aMonthsAbbrevSt[iMonth];
705
- } else if (oField.digits == 4) {
747
+ } else if (oField.digits === 4) {
706
748
  return oFormat.aMonthsWideSt[iMonth];
707
749
  } else if (oField.digits > 4) {
708
750
  return oFormat.aMonthsNarrowSt[iMonth];
@@ -711,20 +753,18 @@ DateFormat.prototype.oSymbols = {
711
753
  }
712
754
  },
713
755
  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;
756
+ var iMonth, sPart, bPartInvalid, bValid, aMonthsVariants = [
757
+ oFormat.aMonthsWide,
758
+ oFormat.aMonthsWideSt,
759
+ oFormat.aMonthsAbbrev,
760
+ oFormat.aMonthsAbbrevSt,
761
+ oFormat.aMonthsNarrow,
762
+ oFormat.aMonthsNarrowSt
763
+ ];
725
764
  if (oPart.digits < 3) {
726
765
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
727
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
766
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
767
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
728
768
  iMonth = parseInt(sPart) - 1;
729
769
  if (oConfig.strict && (iMonth > 11 || iMonth < 0)) {
730
770
  bValid = false;
@@ -747,12 +787,15 @@ DateFormat.prototype.oSymbols = {
747
787
  length: sPart ? sPart.length : 0,
748
788
  valid: bValid
749
789
  };
790
+ },
791
+ isNumeric: function (iDigits) {
792
+ return iDigits < 3;
750
793
  }
751
- },
752
- 'w': {
794
+ }),
795
+ 'w': DateFormat._createPatternSymbol({
753
796
  name: 'weekInYear',
754
797
  format: function (oField, oDate, bUTC, oFormat) {
755
- var oWeek = oDate.getUTCWeek();
798
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
756
799
  var iWeek = oWeek.week;
757
800
  var sWeek = String(iWeek + 1);
758
801
  if (oField.digits < 3) {
@@ -763,15 +806,13 @@ DateFormat.prototype.oSymbols = {
763
806
  return sWeek;
764
807
  },
765
808
  parse: function (sValue, oPart, oFormat, oConfig) {
766
- var bValid;
767
- var sPart;
768
- var iWeek;
769
- var iLength = 0;
809
+ var sPart, bPartInvalid, bValid, iWeek, iLength = 0;
770
810
  if (oPart.digits < 3) {
771
811
  sPart = oParseHelper.findNumbers(sValue, 2);
772
812
  iLength = sPart.length;
773
813
  iWeek = parseInt(sPart) - 1;
774
- bValid = oParseHelper.checkValid(oPart.type, !sPart, oFormat);
814
+ bPartInvalid = !sPart || oConfig.exactLength && iLength < 2;
815
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
775
816
  } else {
776
817
  sPart = oFormat.oLocaleData.getCalendarWeek(oPart.digits === 3 ? 'narrow' : 'wide');
777
818
  sPart = sPart.replace('{0}', '([0-9]+)');
@@ -788,35 +829,21 @@ DateFormat.prototype.oSymbols = {
788
829
  valid: bValid,
789
830
  week: iWeek
790
831
  };
791
- }
792
- },
793
- 'W': {
794
- name: 'weekInMonth',
795
- format: function (oField, oDate) {
796
- return '';
797
832
  },
798
- parse: function () {
799
- return {};
833
+ isNumeric: function (iDigits) {
834
+ return iDigits < 3;
800
835
  }
801
- },
802
- 'D': {
803
- name: 'dayInYear',
804
- format: function (oField, oDate) {
805
- },
806
- parse: function () {
807
- return {};
808
- }
809
- },
810
- 'd': {
836
+ }),
837
+ 'W': DateFormat._createPatternSymbol({ name: 'weekInMonth' }),
838
+ 'D': DateFormat._createPatternSymbol({ name: 'dayInYear' }),
839
+ 'd': DateFormat._createPatternSymbol({
811
840
  name: 'day',
812
841
  format: function (oField, oDate) {
813
842
  var iDate = oDate.getUTCDate();
814
843
  return String(iDate).padStart(oField.digits, '0');
815
844
  },
816
845
  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);
846
+ 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
847
  if (oConfig.strict && (iDay > 31 || iDay < 1)) {
821
848
  bValid = false;
822
849
  }
@@ -825,15 +852,16 @@ DateFormat.prototype.oSymbols = {
825
852
  length: sPart.length,
826
853
  valid: bValid
827
854
  };
828
- }
829
- },
830
- 'Q': {
855
+ },
856
+ isNumeric: true
857
+ }),
858
+ 'Q': DateFormat._createPatternSymbol({
831
859
  name: 'quarter',
832
860
  format: function (oField, oDate, bUTC, oFormat) {
833
861
  var iQuarter = oDate.getUTCQuarter();
834
- if (oField.digits == 3) {
862
+ if (oField.digits === 3) {
835
863
  return oFormat.aQuartersAbbrev[iQuarter];
836
- } else if (oField.digits == 4) {
864
+ } else if (oField.digits === 4) {
837
865
  return oFormat.aQuartersWide[iQuarter];
838
866
  } else if (oField.digits > 4) {
839
867
  return oFormat.aQuartersNarrow[iQuarter];
@@ -842,9 +870,7 @@ DateFormat.prototype.oSymbols = {
842
870
  }
843
871
  },
844
872
  parse: function (sValue, oPart, oFormat, oConfig) {
845
- var bValid;
846
- var iQuarter;
847
- var sPart;
873
+ var sPart, bPartInvalid, iQuarter, bValid;
848
874
  var aQuartersVariants = [
849
875
  oFormat.aQuartersWide,
850
876
  oFormat.aQuartersWideSt,
@@ -855,7 +881,8 @@ DateFormat.prototype.oSymbols = {
855
881
  ];
856
882
  if (oPart.digits < 3) {
857
883
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
858
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
884
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
885
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
859
886
  iQuarter = parseInt(sPart) - 1;
860
887
  if (oConfig.strict && iQuarter > 3) {
861
888
  bValid = false;
@@ -878,15 +905,18 @@ DateFormat.prototype.oSymbols = {
878
905
  quarter: iQuarter,
879
906
  valid: bValid
880
907
  };
908
+ },
909
+ isNumeric: function (iDigits) {
910
+ return iDigits < 3;
881
911
  }
882
- },
883
- 'q': {
912
+ }),
913
+ 'q': DateFormat._createPatternSymbol({
884
914
  name: 'quarterStandalone',
885
915
  format: function (oField, oDate, bUTC, oFormat) {
886
916
  var iQuarter = oDate.getUTCQuarter();
887
- if (oField.digits == 3) {
917
+ if (oField.digits === 3) {
888
918
  return oFormat.aQuartersAbbrevSt[iQuarter];
889
- } else if (oField.digits == 4) {
919
+ } else if (oField.digits === 4) {
890
920
  return oFormat.aQuartersWideSt[iQuarter];
891
921
  } else if (oField.digits > 4) {
892
922
  return oFormat.aQuartersNarrowSt[iQuarter];
@@ -895,9 +925,7 @@ DateFormat.prototype.oSymbols = {
895
925
  }
896
926
  },
897
927
  parse: function (sValue, oPart, oFormat, oConfig) {
898
- var bValid;
899
- var iQuarter;
900
- var sPart;
928
+ var sPart, bPartInvalid, iQuarter, bValid;
901
929
  var aQuartersVariants = [
902
930
  oFormat.aQuartersWide,
903
931
  oFormat.aQuartersWideSt,
@@ -908,7 +936,8 @@ DateFormat.prototype.oSymbols = {
908
936
  ];
909
937
  if (oPart.digits < 3) {
910
938
  sPart = oParseHelper.findNumbers(sValue, Math.max(oPart.digits, 2));
911
- bValid = oParseHelper.checkValid(oPart.type, sPart === '', oFormat);
939
+ bPartInvalid = sPart === '' || oConfig.exactLength && sPart.length < 2;
940
+ bValid = oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat);
912
941
  iQuarter = parseInt(sPart) - 1;
913
942
  if (oConfig.strict && iQuarter > 3) {
914
943
  bValid = false;
@@ -931,26 +960,21 @@ DateFormat.prototype.oSymbols = {
931
960
  quarter: iQuarter,
932
961
  valid: bValid
933
962
  };
934
- }
935
- },
936
- 'F': {
937
- name: 'dayOfWeekInMonth',
938
- format: function (oField, oDate, oFormat) {
939
- return '';
940
963
  },
941
- parse: function () {
942
- return {};
964
+ isNumeric: function (iDigits) {
965
+ return iDigits < 3;
943
966
  }
944
- },
945
- 'E': {
967
+ }),
968
+ 'F': DateFormat._createPatternSymbol({ name: 'dayOfWeekInMonth' }),
969
+ 'E': DateFormat._createPatternSymbol({
946
970
  name: 'dayNameInWeek',
947
971
  format: function (oField, oDate, bUTC, oFormat) {
948
972
  var iDay = oDate.getUTCDay();
949
973
  if (oField.digits < 4) {
950
974
  return oFormat.aDaysAbbrev[iDay];
951
- } else if (oField.digits == 4) {
975
+ } else if (oField.digits === 4) {
952
976
  return oFormat.aDaysWide[iDay];
953
- } else if (oField.digits == 5) {
977
+ } else if (oField.digits === 5) {
954
978
  return oFormat.aDaysNarrow[iDay];
955
979
  } else {
956
980
  return oFormat.aDaysShort[iDay];
@@ -978,16 +1002,16 @@ DateFormat.prototype.oSymbols = {
978
1002
  }
979
1003
  }
980
1004
  }
981
- },
982
- 'c': {
1005
+ }),
1006
+ 'c': DateFormat._createPatternSymbol({
983
1007
  name: 'dayNameInWeekStandalone',
984
1008
  format: function (oField, oDate, bUTC, oFormat) {
985
1009
  var iDay = oDate.getUTCDay();
986
1010
  if (oField.digits < 4) {
987
1011
  return oFormat.aDaysAbbrevSt[iDay];
988
- } else if (oField.digits == 4) {
1012
+ } else if (oField.digits === 4) {
989
1013
  return oFormat.aDaysWideSt[iDay];
990
- } else if (oField.digits == 5) {
1014
+ } else if (oField.digits === 5) {
991
1015
  return oFormat.aDaysNarrowSt[iDay];
992
1016
  } else {
993
1017
  return oFormat.aDaysShortSt[iDay];
@@ -1015,67 +1039,120 @@ DateFormat.prototype.oSymbols = {
1015
1039
  }
1016
1040
  }
1017
1041
  }
1018
- },
1019
- 'u': {
1042
+ }),
1043
+ 'u': DateFormat._createPatternSymbol({
1020
1044
  name: 'dayNumberOfWeek',
1021
1045
  format: function (oField, oDate, bUTC, oFormat) {
1022
1046
  var iDay = oDate.getUTCDay();
1023
1047
  return oFormat._adaptDayOfWeek(iDay);
1024
1048
  },
1025
1049
  parse: function (sValue, oPart, oFormat, oConfig) {
1026
- var sPart = oParseHelper.findNumbers(sValue, oPart.digits);
1050
+ var sPart = oParseHelper.findNumbers(sValue, oPart.digits), bPartInvalid = oConfig.exactLength && sPart.length !== oPart.digits;
1027
1051
  return {
1028
1052
  dayNumberOfWeek: parseInt(sPart),
1029
- length: sPart.length
1053
+ length: sPart.length,
1054
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat)
1030
1055
  };
1031
- }
1032
- },
1033
- 'a': {
1056
+ },
1057
+ isNumeric: true
1058
+ }),
1059
+ 'a': DateFormat._createPatternSymbol({
1034
1060
  name: 'amPmMarker',
1035
1061
  format: function (oField, oDate, bUTC, oFormat) {
1036
1062
  var iDayPeriod = oDate.getUTCDayPeriod();
1037
- return oFormat.aDayPeriods[iDayPeriod];
1063
+ if (oField.digits <= 3) {
1064
+ return oFormat.aDayPeriodsAbbrev[iDayPeriod];
1065
+ } else if (oField.digits === 4) {
1066
+ return oFormat.aDayPeriodsWide[iDayPeriod];
1067
+ } else {
1068
+ return oFormat.aDayPeriodsNarrow[iDayPeriod];
1069
+ }
1070
+ },
1071
+ parse: function (sValue, oPart, oFormat, oConfig, sTimezone) {
1072
+ var rAMPM, bAMPMAlternativeCase, oEntry, i, aMatch, normalize, aVariants, aDayPeriodsVariants = [
1073
+ oFormat.aDayPeriodsWide,
1074
+ oFormat.aDayPeriodsAbbrev,
1075
+ oFormat.aDayPeriodsNarrow
1076
+ ];
1077
+ rAMPM = /[aApP](?:\.)?[\x20\xA0]?[mM](?:\.)?/;
1078
+ aMatch = sValue.match(rAMPM);
1079
+ bAMPMAlternativeCase = aMatch && aMatch.index === 0;
1080
+ function normalize(sValue) {
1081
+ return sValue.replace(/[\x20\xA0]/g, '').replace(/\./g, '');
1082
+ }
1083
+ if (bAMPMAlternativeCase) {
1084
+ sValue = normalize(sValue);
1085
+ }
1086
+ for (i = 0; i < aDayPeriodsVariants.length; i += 1) {
1087
+ aVariants = aDayPeriodsVariants[i];
1088
+ if (bAMPMAlternativeCase) {
1089
+ aVariants = aVariants.map(normalize);
1090
+ }
1091
+ oEntry = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
1092
+ if (oEntry.index !== -1) {
1093
+ return {
1094
+ pm: oEntry.index === 1,
1095
+ length: bAMPMAlternativeCase ? aMatch[0].length : oEntry.length
1096
+ };
1097
+ }
1098
+ }
1099
+ return { valid: false };
1100
+ }
1101
+ }),
1102
+ 'B': DateFormat._createPatternSymbol({
1103
+ name: 'flexibleDayPeriod',
1104
+ format: function (oField, oDate, bUTC, oFormat) {
1105
+ var bContainsHour = oFormat.aFormatArray.some(function (oFormatElement) {
1106
+ return 'hHKk'.includes(oFormatElement.symbol);
1107
+ }), sFlexibleDayPeriod = oFormat.oLocaleData.getFlexibleDayPeriodOfTime(oDate.getUTCHours(), oDate.getUTCMinutes());
1108
+ if (bContainsHour) {
1109
+ if (oField.digits <= 3) {
1110
+ return oFormat.oFlexibleDayPeriodsAbbrev[sFlexibleDayPeriod];
1111
+ }
1112
+ if (oField.digits === 4) {
1113
+ return oFormat.oFlexibleDayPeriodsWide[sFlexibleDayPeriod];
1114
+ }
1115
+ return oFormat.oFlexibleDayPeriodsNarrow[sFlexibleDayPeriod];
1116
+ }
1117
+ if (oField.digits <= 3) {
1118
+ return oFormat.oFlexibleDayPeriodsAbbrevSt[sFlexibleDayPeriod];
1119
+ }
1120
+ if (oField.digits === 4) {
1121
+ return oFormat.oFlexibleDayPeriodsWideSt[sFlexibleDayPeriod];
1122
+ }
1123
+ return oFormat.oFlexibleDayPeriodsNarrowSt[sFlexibleDayPeriod];
1038
1124
  },
1039
1125
  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;
1126
+ var i, oFound, oVariant, bContainsHour = oFormat.aFormatArray.some(function (oFormatElement) {
1127
+ return 'hHKk'.includes(oFormatElement.symbol);
1128
+ }), aFlexibleDayPeriodVariants = [
1129
+ oFormat.oFlexibleDayPeriodsWide,
1130
+ oFormat.oFlexibleDayPeriodsAbbrev,
1131
+ oFormat.oFlexibleDayPeriodsNarrow
1132
+ ];
1133
+ if (bContainsHour) {
1134
+ for (i = 0; i < aFlexibleDayPeriodVariants.length; i++) {
1135
+ oVariant = aFlexibleDayPeriodVariants[i];
1136
+ oFound = oParseHelper.findEntry(sValue, Object.values(oVariant), oFormat.oLocaleData.sCLDRLocaleId);
1137
+ if (oFound.index !== -1) {
1138
+ return {
1139
+ flexDayPeriod: Object.keys(oVariant)[oFound.index],
1140
+ length: oFound.length
1141
+ };
1142
+ }
1143
+ }
1061
1144
  }
1062
- return {
1063
- pm: bPM,
1064
- length: iLength
1065
- };
1145
+ return { valid: false };
1066
1146
  }
1067
- },
1068
- 'H': {
1147
+ }),
1148
+ 'H': DateFormat._createPatternSymbol({
1069
1149
  name: 'hour0_23',
1070
1150
  format: function (oField, oDate) {
1071
1151
  var iHours = oDate.getUTCHours();
1072
1152
  return String(iHours).padStart(oField.digits, '0');
1073
1153
  },
1074
1154
  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);
1155
+ 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
1156
  if (oConfig.strict && iHours > 23) {
1080
1157
  bValid = false;
1081
1158
  }
@@ -1084,9 +1161,10 @@ DateFormat.prototype.oSymbols = {
1084
1161
  length: sPart.length,
1085
1162
  valid: bValid
1086
1163
  };
1087
- }
1088
- },
1089
- 'k': {
1164
+ },
1165
+ isNumeric: true
1166
+ }),
1167
+ 'k': DateFormat._createPatternSymbol({
1090
1168
  name: 'hour1_24',
1091
1169
  format: function (oField, oDate) {
1092
1170
  var iHours = oDate.getUTCHours();
@@ -1094,11 +1172,8 @@ DateFormat.prototype.oSymbols = {
1094
1172
  return sHours.padStart(oField.digits, '0');
1095
1173
  },
1096
1174
  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) {
1175
+ 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);
1176
+ if (iHours === 24) {
1102
1177
  iHours = 0;
1103
1178
  }
1104
1179
  if (oConfig.strict && iHours > 23) {
@@ -1109,9 +1184,10 @@ DateFormat.prototype.oSymbols = {
1109
1184
  length: sPart.length,
1110
1185
  valid: bValid
1111
1186
  };
1112
- }
1113
- },
1114
- 'K': {
1187
+ },
1188
+ isNumeric: true
1189
+ }),
1190
+ 'K': DateFormat._createPatternSymbol({
1115
1191
  name: 'hour0_11',
1116
1192
  format: function (oField, oDate) {
1117
1193
  var iHours = oDate.getUTCHours();
@@ -1119,10 +1195,7 @@ DateFormat.prototype.oSymbols = {
1119
1195
  return sHours.padStart(oField.digits, '0');
1120
1196
  },
1121
1197
  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);
1198
+ 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
1199
  if (oConfig.strict && iHours > 11) {
1127
1200
  bValid = false;
1128
1201
  }
@@ -1131,16 +1204,17 @@ DateFormat.prototype.oSymbols = {
1131
1204
  length: sPart.length,
1132
1205
  valid: bValid
1133
1206
  };
1134
- }
1135
- },
1136
- 'h': {
1207
+ },
1208
+ isNumeric: true
1209
+ }),
1210
+ 'h': DateFormat._createPatternSymbol({
1137
1211
  name: 'hour1_12',
1138
1212
  format: function (oField, oDate) {
1139
1213
  var iHours = oDate.getUTCHours();
1140
1214
  var sHours;
1141
1215
  if (iHours > 12) {
1142
1216
  sHours = String(iHours - 12);
1143
- } else if (iHours == 0) {
1217
+ } else if (iHours === 0) {
1144
1218
  sHours = '12';
1145
1219
  } else {
1146
1220
  sHours = String(iHours);
@@ -1148,11 +1222,8 @@ DateFormat.prototype.oSymbols = {
1148
1222
  return sHours.padStart(oField.digits, '0');
1149
1223
  },
1150
1224
  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) {
1225
+ 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);
1226
+ if (iHours === 12) {
1156
1227
  iHours = 0;
1157
1228
  bPM = bPM === undefined ? true : bPM;
1158
1229
  }
@@ -1165,19 +1236,17 @@ DateFormat.prototype.oSymbols = {
1165
1236
  pm: bPM,
1166
1237
  valid: bValid
1167
1238
  };
1168
- }
1169
- },
1170
- 'm': {
1239
+ },
1240
+ isNumeric: true
1241
+ }),
1242
+ 'm': DateFormat._createPatternSymbol({
1171
1243
  name: 'minute',
1172
1244
  format: function (oField, oDate) {
1173
1245
  var iMinutes = oDate.getUTCMinutes();
1174
1246
  return String(iMinutes).padStart(oField.digits, '0');
1175
1247
  },
1176
1248
  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);
1249
+ 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
1250
  if (oConfig.strict && iMinutes > 59) {
1182
1251
  bValid = false;
1183
1252
  }
@@ -1186,19 +1255,17 @@ DateFormat.prototype.oSymbols = {
1186
1255
  minute: iMinutes,
1187
1256
  valid: bValid
1188
1257
  };
1189
- }
1190
- },
1191
- 's': {
1258
+ },
1259
+ isNumeric: true
1260
+ }),
1261
+ 's': DateFormat._createPatternSymbol({
1192
1262
  name: 'second',
1193
1263
  format: function (oField, oDate) {
1194
1264
  var iSeconds = oDate.getUTCSeconds();
1195
1265
  return String(iSeconds).padStart(oField.digits, '0');
1196
1266
  },
1197
1267
  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);
1268
+ 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
1269
  if (oConfig.strict && iSeconds > 59) {
1203
1270
  bValid = false;
1204
1271
  }
@@ -1207,9 +1274,10 @@ DateFormat.prototype.oSymbols = {
1207
1274
  second: iSeconds,
1208
1275
  valid: bValid
1209
1276
  };
1210
- }
1211
- },
1212
- 'S': {
1277
+ },
1278
+ isNumeric: true
1279
+ }),
1280
+ 'S': DateFormat._createPatternSymbol({
1213
1281
  name: 'fractionalsecond',
1214
1282
  format: function (oField, oDate) {
1215
1283
  var iMilliseconds = oDate.getUTCMilliseconds();
@@ -1220,18 +1288,19 @@ DateFormat.prototype.oSymbols = {
1220
1288
  return sFractionalseconds;
1221
1289
  },
1222
1290
  parse: function (sValue, oPart, oFormat, oConfig) {
1223
- var sPart = oParseHelper.findNumbers(sValue, oPart.digits);
1224
- var iLength = sPart.length;
1291
+ var sPart = oParseHelper.findNumbers(sValue, oPart.digits), iLength = sPart.length, bPartInvalid = oConfig.exactLength && iLength < oPart.digits;
1225
1292
  sPart = sPart.substr(0, 3);
1226
1293
  sPart = sPart.padEnd(3, '0');
1227
1294
  var iMilliseconds = parseInt(sPart);
1228
1295
  return {
1229
1296
  length: iLength,
1230
- millisecond: iMilliseconds
1297
+ millisecond: iMilliseconds,
1298
+ valid: oParseHelper.checkValid(oPart.type, bPartInvalid, oFormat)
1231
1299
  };
1232
- }
1233
- },
1234
- 'z': {
1300
+ },
1301
+ isNumeric: true
1302
+ }),
1303
+ 'z': DateFormat._createPatternSymbol({
1235
1304
  name: 'timezoneGeneral',
1236
1305
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1237
1306
  if (oField.digits > 3 && oDate.getTimezoneLong && oDate.getTimezoneLong()) {
@@ -1245,7 +1314,7 @@ DateFormat.prototype.oSymbols = {
1245
1314
  var bPositiveOffset = iTimezoneOffset > 0;
1246
1315
  var iHourOffset = Math.floor(iTZOffset / 60);
1247
1316
  var iMinuteOffset = Math.floor(iTZOffset % 60);
1248
- if (!bUTC && iTZOffset != 0) {
1317
+ if (!bUTC && iTZOffset !== 0) {
1249
1318
  sTimeZone += bPositiveOffset ? '-' : '+';
1250
1319
  sTimeZone += String(iHourOffset).padStart(2, '0');
1251
1320
  sTimeZone += ':';
@@ -1279,8 +1348,8 @@ DateFormat.prototype.oSymbols = {
1279
1348
  tzDiff: iTZDiff
1280
1349
  };
1281
1350
  }
1282
- },
1283
- 'Z': {
1351
+ }),
1352
+ 'Z': DateFormat._createPatternSymbol({
1284
1353
  name: 'timezoneRFC822',
1285
1354
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1286
1355
  var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
@@ -1299,8 +1368,8 @@ DateFormat.prototype.oSymbols = {
1299
1368
  parse: function (sValue, oPart, oFormat, oConfig) {
1300
1369
  return oParseHelper.parseTZ(sValue, false);
1301
1370
  }
1302
- },
1303
- 'X': {
1371
+ }),
1372
+ 'X': DateFormat._createPatternSymbol({
1304
1373
  name: 'timezoneISO8601',
1305
1374
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1306
1375
  var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
@@ -1309,7 +1378,7 @@ DateFormat.prototype.oSymbols = {
1309
1378
  var iHourOffset = Math.floor(iTZOffset / 60);
1310
1379
  var iMinuteOffset = Math.floor(iTZOffset % 60);
1311
1380
  var sTimeZone = '';
1312
- if (!bUTC && iTZOffset != 0) {
1381
+ if (!bUTC && iTZOffset !== 0) {
1313
1382
  sTimeZone += bPositiveOffset ? '-' : '+';
1314
1383
  sTimeZone += String(iHourOffset).padStart(2, '0');
1315
1384
  if (oField.digits > 1 || iMinuteOffset > 0) {
@@ -1333,12 +1402,12 @@ DateFormat.prototype.oSymbols = {
1333
1402
  return oParseHelper.parseTZ(sValue, oPart.digits === 3 || oPart.digits === 5);
1334
1403
  }
1335
1404
  }
1336
- },
1337
- 'V': {
1405
+ }),
1406
+ 'V': DateFormat._createPatternSymbol({
1338
1407
  name: 'timezoneID',
1339
1408
  format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1340
1409
  if (!bUTC && oField.digits === 2) {
1341
- return sTimezone;
1410
+ return oFormat.oLocaleData.getTimezoneTranslations()[sTimezone] || sTimezone;
1342
1411
  }
1343
1412
  return '';
1344
1413
  },
@@ -1348,24 +1417,33 @@ DateFormat.prototype.oSymbols = {
1348
1417
  length: 0
1349
1418
  };
1350
1419
  if (oPart.digits === 2) {
1351
- if (sValue === sTimezone) {
1352
- oTimezoneParsed.timezone = sTimezone;
1353
- oTimezoneParsed.length = sTimezone.length;
1354
- return oTimezoneParsed;
1420
+ var mTimezoneTranslations = oFormat.oLocaleData.getTimezoneTranslations();
1421
+ if (sValue === mTimezoneTranslations[sTimezone]) {
1422
+ return {
1423
+ timezone: sTimezone,
1424
+ length: sValue.length
1425
+ };
1355
1426
  }
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;
1427
+ var aTimezoneTranslations = Object.values(mTimezoneTranslations);
1428
+ var oTimezoneResult = oParseHelper.findEntry(sValue, aTimezoneTranslations, oFormat.oLocaleData.sCLDRLocaleId);
1429
+ if (oTimezoneResult.index !== -1) {
1430
+ return {
1431
+ timezone: Object.keys(mTimezoneTranslations)[oTimezoneResult.index],
1432
+ length: oTimezoneResult.length
1433
+ };
1434
+ }
1435
+ var sCurrentValue = '';
1436
+ for (var i = 0; i < sValue.length; i++) {
1437
+ sCurrentValue += sValue[i];
1438
+ if (TimezoneUtil.isValidTimezone(sCurrentValue)) {
1439
+ oTimezoneParsed.timezone = sCurrentValue;
1440
+ oTimezoneParsed.length = sCurrentValue.length;
1363
1441
  }
1364
1442
  }
1365
1443
  }
1366
1444
  return oTimezoneParsed;
1367
1445
  }
1368
- }
1446
+ })
1369
1447
  };
1370
1448
  DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1371
1449
  if (this.oFormatOptions.relative) {
@@ -1383,7 +1461,7 @@ DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1383
1461
  aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this, sTimezone));
1384
1462
  }
1385
1463
  sResult = aBuffer.join('');
1386
- if (Core.getConfiguration().getOriginInfo()) {
1464
+ if (Configuration.getOriginInfo()) {
1387
1465
  sResult = new String(sResult);
1388
1466
  sResult.originInfo = {
1389
1467
  source: 'Common Locale Data Repository',
@@ -1409,7 +1487,7 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1409
1487
  if (bUTC === undefined) {
1410
1488
  bUTC = this.oFormatOptions.UTC;
1411
1489
  }
1412
- sTimezone = sTimezone || Core.getConfiguration().getTimezone();
1490
+ sTimezone = sTimezone || Configuration.getTimezone();
1413
1491
  if (Array.isArray(vJSDate)) {
1414
1492
  if (!this.oFormatOptions.interval) {
1415
1493
  Log.error('Non-interval DateFormat can\'t format more than one date instance.');
@@ -1441,7 +1519,7 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1441
1519
  } else {
1442
1520
  if (!isValidDateObject(vJSDate)) {
1443
1521
  if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE && this.oFormatOptions.pattern.includes('VV')) {
1444
- return sTimezone;
1522
+ return this.oLocaleData.getTimezoneTranslations()[sTimezone] || sTimezone;
1445
1523
  }
1446
1524
  Log.error('The given date instance isn\'t valid.');
1447
1525
  return '';
@@ -1453,30 +1531,36 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1453
1531
  vJSDate = convertToTimezone(vJSDate, sTimezone, bUTC);
1454
1532
  sResult = this._format(vJSDate, bUTC, sTimezone);
1455
1533
  }
1456
- if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1534
+ if (sCalendarType === CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1457
1535
  sResult = sResult.replace(/(^|[^\d])1年/g, '$1元年');
1458
1536
  }
1459
1537
  return sResult;
1460
1538
  };
1539
+ DateFormat.prototype._useCustomIntervalDelimiter = function (oDiffFields) {
1540
+ var aTokens;
1541
+ if (!this.oFormatOptions.intervalDelimiter) {
1542
+ return false;
1543
+ }
1544
+ if (this.oFormatOptions.format) {
1545
+ aTokens = this.oLocaleData._parseSkeletonFormat(this.oFormatOptions.format);
1546
+ return aTokens.some(function (oToken) {
1547
+ return oDiffFields[oToken.group];
1548
+ });
1549
+ }
1550
+ return true;
1551
+ };
1461
1552
  DateFormat.prototype._formatInterval = function (aJSDates, bUTC) {
1462
- var sCalendarType = this.oFormatOptions.calendarType;
1463
- var oFromDate = UniversalDate.getInstance(aJSDates[0], sCalendarType);
1464
- var oToDate = UniversalDate.getInstance(aJSDates[1], sCalendarType);
1465
- var oDate;
1466
- var oPart;
1467
- var sSymbol;
1468
- var aBuffer = [];
1469
- var sPattern;
1470
- var aFormatArray = [];
1471
- var oDiffField = this._getGreatestDiffField([
1472
- oFromDate,
1473
- oToDate
1474
- ]);
1475
- if (!oDiffField) {
1553
+ var oDate, oPart, sPattern, sSymbol, aBuffer = [], sCalendarType = this.oFormatOptions.calendarType, aFormatArray = [], oFromDate = UniversalDate.getInstance(aJSDates[0], sCalendarType), oToDate = UniversalDate.getInstance(aJSDates[1], sCalendarType), oDiffFields = this._getDiffFields([
1554
+ oFromDate,
1555
+ oToDate
1556
+ ]);
1557
+ if (!oDiffFields) {
1476
1558
  return this._format(aJSDates[0], bUTC);
1477
1559
  }
1478
- if (this.oFormatOptions.format) {
1479
- sPattern = this.oLocaleData.getCustomIntervalPattern(this.oFormatOptions.format, oDiffField, sCalendarType);
1560
+ if (this._useCustomIntervalDelimiter(oDiffFields)) {
1561
+ sPattern = this.intervalPatterns[0];
1562
+ } else if (this.oFormatOptions.format) {
1563
+ sPattern = this.oLocaleData.getCustomIntervalPattern(this.oFormatOptions.format, oDiffFields, sCalendarType);
1480
1564
  } else {
1481
1565
  sPattern = this.oLocaleData.getCombinedIntervalPattern(this.oFormatOptions.pattern, sCalendarType);
1482
1566
  }
@@ -1504,7 +1588,7 @@ var mFieldToGroup = {
1504
1588
  Minutes: 'Minute',
1505
1589
  Seconds: 'Second'
1506
1590
  };
1507
- DateFormat.prototype._getGreatestDiffField = function (aDates) {
1591
+ DateFormat.prototype._getDiffFields = function (aDates) {
1508
1592
  var bDiffFound = false, mDiff = {};
1509
1593
  this.aIntervalCompareFields.forEach(function (sField) {
1510
1594
  var sGetterPrefix = 'getUTC', sMethodName = sGetterPrefix + sField, sFieldGroup = mFieldToGroup[sField], vFromValue = aDates[0][sMethodName].apply(aDates[0]), vToValue = aDates[1][sMethodName].apply(aDates[1]);
@@ -1519,21 +1603,28 @@ DateFormat.prototype._getGreatestDiffField = function (aDates) {
1519
1603
  return null;
1520
1604
  };
1521
1605
  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
- };
1606
+ var sFlexibleDayPeriod, oNextPart, oPart, bPM, oPrevPart, oResult, sSubValue, oDateValue = {
1607
+ valid: true,
1608
+ lastTimezonePatternSymbol: ''
1609
+ }, iIndex = 0, oParseConf = {
1610
+ formatArray: aFormatArray,
1611
+ dateValue: oDateValue,
1612
+ strict: bStrict
1613
+ }, that = this;
1614
+ function getSymbol(oPart0) {
1615
+ return that.oSymbols[oPart0.symbol || ''];
1616
+ }
1617
+ function isNumeric(oPart0) {
1618
+ return !!oPart0 && getSymbol(oPart0).isNumeric(oPart0.digits);
1619
+ }
1532
1620
  for (var i = 0; i < aFormatArray.length; i++) {
1533
1621
  sSubValue = sValue.substr(iIndex);
1534
1622
  oPart = aFormatArray[i];
1623
+ oPrevPart = aFormatArray[i - 1];
1624
+ oNextPart = aFormatArray[i + 1];
1535
1625
  oParseConf.index = i;
1536
- oResult = this.oSymbols[oPart.symbol || ''].parse(sSubValue, oPart, this, oParseConf, sTimezone) || {};
1626
+ oParseConf.exactLength = isNumeric(oPart) && (isNumeric(oPrevPart) || isNumeric(oNextPart));
1627
+ oResult = getSymbol(oPart).parse(sSubValue, oPart, this, oParseConf, sTimezone) || {};
1537
1628
  if (oResult.tzDiff !== undefined || oResult.timezone) {
1538
1629
  oResult.lastTimezonePatternSymbol = oPart.symbol;
1539
1630
  }
@@ -1544,7 +1635,12 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict, sTi
1544
1635
  iIndex += oResult.length || 0;
1545
1636
  }
1546
1637
  oDateValue.index = iIndex;
1547
- if (oDateValue.pm) {
1638
+ bPM = oDateValue.pm;
1639
+ if (oDateValue.flexDayPeriod && oDateValue.hour * 60 + (oDateValue.minute || 0) < 720) {
1640
+ sFlexibleDayPeriod = this.oLocaleData.getFlexibleDayPeriodOfTime(oDateValue.hour + 12, oDateValue.minute || 0);
1641
+ bPM = oDateValue.flexDayPeriod === sFlexibleDayPeriod;
1642
+ }
1643
+ if (bPM) {
1548
1644
  oDateValue.hour += 12;
1549
1645
  }
1550
1646
  if (oDateValue.dayNumberOfWeek === undefined && oDateValue.dayOfWeek !== undefined) {
@@ -1601,13 +1697,24 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1601
1697
  }.bind(this));
1602
1698
  return aDateValues;
1603
1699
  };
1700
+ function getCalendarWeekParameter(oFormatOptions) {
1701
+ if (oFormatOptions.calendarWeekNumbering) {
1702
+ return oFormatOptions.calendarWeekNumbering;
1703
+ } else if (oFormatOptions.firstDayOfWeek !== undefined && oFormatOptions.minimalDaysInFirstWeek !== undefined) {
1704
+ return {
1705
+ firstDayOfWeek: oFormatOptions.firstDayOfWeek,
1706
+ minimalDaysInFirstWeek: oFormatOptions.minimalDaysInFirstWeek
1707
+ };
1708
+ }
1709
+ return undefined;
1710
+ }
1604
1711
  var convertToTimezone = function (oJSDate, sTimezone, bUTC) {
1605
1712
  if (!bUTC && isValidDateObject(oJSDate)) {
1606
1713
  return TimezoneUtil.convertToTimezone(oJSDate, sTimezone);
1607
1714
  }
1608
1715
  return oJSDate;
1609
1716
  };
1610
- var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone) {
1717
+ var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone, oFormatOptions, oLocale) {
1611
1718
  if (!oDateValue.valid) {
1612
1719
  return null;
1613
1720
  }
@@ -1628,7 +1735,7 @@ var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone
1628
1735
  oDate.setUTCWeek({
1629
1736
  year: oDateValue.weekYear || oDateValue.year,
1630
1737
  week: oDateValue.week
1631
- });
1738
+ }, oLocale, getCalendarWeekParameter(oFormatOptions));
1632
1739
  if (oDateValue.dayNumberOfWeek !== undefined) {
1633
1740
  oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1634
1741
  }
@@ -1643,7 +1750,7 @@ var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone
1643
1750
  }
1644
1751
  }
1645
1752
  if (oDateValue.tzDiff) {
1646
- oDate.setUTCSeconds((oDateValue.second || 0) + oDateValue.tzDiff);
1753
+ oDate.setUTCSeconds(oDate.getUTCSeconds() + oDateValue.tzDiff);
1647
1754
  }
1648
1755
  return oDate;
1649
1756
  };
@@ -1694,11 +1801,11 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1694
1801
  sValue = sValue == null ? '' : String(sValue).trim();
1695
1802
  var oDateValue;
1696
1803
  var sCalendarType = this.oFormatOptions.calendarType;
1697
- sTimezone = sTimezone || Core.getConfiguration().getTimezone();
1804
+ sTimezone = sTimezone || Configuration.getTimezone();
1698
1805
  if (bStrict === undefined) {
1699
1806
  bStrict = this.oFormatOptions.strictParsing;
1700
1807
  }
1701
- if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1808
+ if (sCalendarType === CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1702
1809
  sValue = sValue.replace(/元年/g, '1年');
1703
1810
  }
1704
1811
  if (!this.oFormatOptions.interval) {
@@ -1710,7 +1817,7 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1710
1817
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1711
1818
  oDateValue.valid = false;
1712
1819
  }
1713
- oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone);
1820
+ oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1714
1821
  if (oJSDate) {
1715
1822
  if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1716
1823
  var bShowTimezone = this.oFormatOptions.showTimezone === undefined || this.oFormatOptions.showTimezone;
@@ -1735,11 +1842,11 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1735
1842
  } else {
1736
1843
  var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict, sTimezone);
1737
1844
  var oJSDate1, oJSDate2;
1738
- if (aDateValues && aDateValues.length == 2) {
1845
+ if (aDateValues && aDateValues.length === 2) {
1739
1846
  var oDateValue1 = mergeWithoutOverwrite(aDateValues[0], aDateValues[1]);
1740
1847
  var oDateValue2 = mergeWithoutOverwrite(aDateValues[1], aDateValues[0]);
1741
- oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict, sTimezone);
1742
- oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict, sTimezone);
1848
+ oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1849
+ oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1743
1850
  if (oJSDate1 && oJSDate2) {
1744
1851
  if (this.oFormatOptions.singleIntervalValue && oJSDate1.getTime() === oJSDate2.getTime()) {
1745
1852
  return [
@@ -1762,7 +1869,7 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1762
1869
  }
1763
1870
  }
1764
1871
  }
1765
- if (!this.bIsFallback) {
1872
+ if (this.aFallbackFormats) {
1766
1873
  var vDate;
1767
1874
  this.aFallbackFormats.every(function (oFallbackFormat) {
1768
1875
  vDate = oFallbackFormat.parse(sValue, bUTCInputParameter, bStrict);
@@ -1794,20 +1901,20 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1794
1901
  for (i = 0; i < sPattern.length; i++) {
1795
1902
  var sCurChar = sPattern.charAt(i), sNextChar, sPrevChar, sPrevPrevChar;
1796
1903
  if (bQuoted) {
1797
- if (sCurChar == '\'') {
1904
+ if (sCurChar === '\'') {
1798
1905
  sPrevChar = sPattern.charAt(i - 1);
1799
1906
  sPrevPrevChar = sPattern.charAt(i - 2);
1800
1907
  sNextChar = sPattern.charAt(i + 1);
1801
- if (sPrevChar == '\'' && sPrevPrevChar != '\'') {
1908
+ if (sPrevChar === '\'' && sPrevPrevChar !== '\'') {
1802
1909
  bQuoted = false;
1803
- } else if (sNextChar == '\'') {
1910
+ } else if (sNextChar === '\'') {
1804
1911
  i += 1;
1805
1912
  } else {
1806
1913
  bQuoted = false;
1807
1914
  continue;
1808
1915
  }
1809
1916
  }
1810
- if (sState == 'text') {
1917
+ if (sState === 'text') {
1811
1918
  oCurrentObject.value += sCurChar;
1812
1919
  } else {
1813
1920
  oCurrentObject = {
@@ -1818,11 +1925,11 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1818
1925
  sState = 'text';
1819
1926
  }
1820
1927
  } else {
1821
- if (sCurChar == '\'') {
1928
+ if (sCurChar === '\'') {
1822
1929
  bQuoted = true;
1823
1930
  } else if (this.oSymbols[sCurChar]) {
1824
1931
  sNewState = this.oSymbols[sCurChar].name;
1825
- if (sState == sNewState) {
1932
+ if (sState === sNewState) {
1826
1933
  oCurrentObject.digits++;
1827
1934
  } else {
1828
1935
  oCurrentObject = {
@@ -1842,7 +1949,7 @@ DateFormat.prototype.parseCldrDatePattern = function (sPattern) {
1842
1949
  }
1843
1950
  }
1844
1951
  } else {
1845
- if (sState == 'text') {
1952
+ if (sState === 'text') {
1846
1953
  oCurrentObject.value += sCurChar;
1847
1954
  } else {
1848
1955
  oCurrentObject = {
@@ -1878,57 +1985,78 @@ DateFormat.prototype.parseRelative = function (sValue, bUTC) {
1878
1985
  }
1879
1986
  }
1880
1987
  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
- }
1988
+ var oResult = UI5Date.getInstance();
1914
1989
  if (bUTC) {
1915
- return oJSDate;
1990
+ oResult.setUTCFullYear(oResult.getFullYear(), oResult.getMonth(), oResult.getDate());
1991
+ oResult.setUTCHours(oResult.getHours(), oResult.getMinutes(), oResult.getSeconds(), oResult.getMilliseconds());
1992
+ switch (sScale) {
1993
+ case 'second':
1994
+ oResult.setUTCSeconds(oResult.getUTCSeconds() + iDiff);
1995
+ break;
1996
+ case 'minute':
1997
+ oResult.setUTCMinutes(oResult.getUTCMinutes() + iDiff);
1998
+ break;
1999
+ case 'hour':
2000
+ oResult.setUTCHours(oResult.getUTCHours() + iDiff);
2001
+ break;
2002
+ case 'day':
2003
+ oResult.setUTCDate(oResult.getUTCDate() + iDiff);
2004
+ break;
2005
+ case 'week':
2006
+ oResult.setUTCDate(oResult.getUTCDate() + iDiff * 7);
2007
+ break;
2008
+ case 'month':
2009
+ oResult.setUTCMonth(oResult.getUTCMonth() + iDiff);
2010
+ break;
2011
+ case 'quarter':
2012
+ oResult.setUTCMonth(oResult.getUTCMonth() + iDiff * 3);
2013
+ break;
2014
+ case 'year':
2015
+ oResult.setUTCFullYear(oResult.getUTCFullYear() + iDiff);
2016
+ break;
2017
+ }
1916
2018
  } else {
1917
- return new Date(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate(), oJSDate.getUTCHours(), oJSDate.getUTCMinutes(), oJSDate.getUTCSeconds(), oJSDate.getUTCMilliseconds());
2019
+ switch (sScale) {
2020
+ case 'second':
2021
+ oResult.setSeconds(oResult.getSeconds() + iDiff);
2022
+ break;
2023
+ case 'minute':
2024
+ oResult.setMinutes(oResult.getMinutes() + iDiff);
2025
+ break;
2026
+ case 'hour':
2027
+ oResult.setHours(oResult.getHours() + iDiff);
2028
+ break;
2029
+ case 'day':
2030
+ oResult.setDate(oResult.getDate() + iDiff);
2031
+ break;
2032
+ case 'week':
2033
+ oResult.setDate(oResult.getDate() + iDiff * 7);
2034
+ break;
2035
+ case 'month':
2036
+ oResult.setMonth(oResult.getMonth() + iDiff);
2037
+ break;
2038
+ case 'quarter':
2039
+ oResult.setMonth(oResult.getMonth() + iDiff * 3);
2040
+ break;
2041
+ case 'year':
2042
+ oResult.setFullYear(oResult.getFullYear() + iDiff);
2043
+ break;
2044
+ }
1918
2045
  }
2046
+ return oResult;
1919
2047
  }
1920
2048
  };
1921
2049
  DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange, sTimezone) {
1922
- var oToday = convertToTimezone(new Date(), sTimezone), oDateUTC, sScale = this.oFormatOptions.relativeScale || 'day', iDiff, sPattern, iDiffSeconds;
2050
+ var oDateUTC, iDiff, iDiffSeconds, sPattern, oToday = convertToTimezone(new Date(), sTimezone), sScale = this.oFormatOptions.relativeScale || 'day';
1923
2051
  iDiffSeconds = (oJSDate.getTime() - oToday.getTime()) / 1000;
1924
- if (this.oFormatOptions.relativeScale == 'auto') {
2052
+ if (this.oFormatOptions.relativeScale === 'auto') {
1925
2053
  sScale = this._getScale(iDiffSeconds, this.aRelativeScales);
1926
2054
  sScale = fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds);
1927
2055
  }
1928
2056
  if (!aRange) {
1929
2057
  aRange = this._mRanges[sScale];
1930
2058
  }
1931
- if (sScale == 'year' || sScale == 'month' || sScale == 'day') {
2059
+ if (sScale === 'year' || sScale === 'month' || sScale === 'day') {
1932
2060
  oToday = new Date(Date.UTC(oToday.getUTCFullYear(), oToday.getUTCMonth(), oToday.getUTCDate()));
1933
2061
  oDateUTC = new Date(0);
1934
2062
  oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
@@ -1938,7 +2066,7 @@ DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange, sTimezone
1938
2066
  oToday,
1939
2067
  oJSDate
1940
2068
  ]);
1941
- if (this.oFormatOptions.relativeScale != 'auto' && (iDiff < aRange[0] || iDiff > aRange[1])) {
2069
+ if (this.oFormatOptions.relativeScale !== 'auto' && (iDiff < aRange[0] || iDiff > aRange[1])) {
1942
2070
  return null;
1943
2071
  }
1944
2072
  sPattern = this.oLocaleData.getRelativePattern(sScale, iDiff, iDiffSeconds > 0, this.oFormatOptions.relativeStyle);
@@ -2015,7 +2143,7 @@ function fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds) {
2015
2143
  return sScale;
2016
2144
  }
2017
2145
  function cutDateFields(oDate, iStartIndex) {
2018
- var aFields = [
2146
+ var sMethodName, aFields = [
2019
2147
  'FullYear',
2020
2148
  'Month',
2021
2149
  'Date',
@@ -2023,8 +2151,7 @@ function cutDateFields(oDate, iStartIndex) {
2023
2151
  'Minutes',
2024
2152
  'Seconds',
2025
2153
  'Milliseconds'
2026
- ], sMethodName;
2027
- var oDateCopy = new Date(oDate.getTime());
2154
+ ], oDateCopy = new Date(oDate.getTime());
2028
2155
  for (var i = iStartIndex; i < aFields.length; i++) {
2029
2156
  sMethodName = 'setUTC' + aFields[iStartIndex];
2030
2157
  oDateCopy[sMethodName].apply(oDateCopy, [0]);
@@ -2067,7 +2194,12 @@ var mRelativeDiffs = {
2067
2194
  }
2068
2195
  };
2069
2196
  DateFormat.prototype._adaptDayOfWeek = function (iDayOfWeek) {
2070
- var iFirstDayOfWeek = LocaleData.getInstance(Core.getConfiguration().getFormatSettings().getFormatLocale()).getFirstDayOfWeek();
2197
+ var vCalendarWeekParameter = getCalendarWeekParameter(this.oFormatOptions), iFirstDayOfWeek;
2198
+ if (typeof vCalendarWeekParameter === 'object') {
2199
+ iFirstDayOfWeek = vCalendarWeekParameter.firstDayOfWeek;
2200
+ } else {
2201
+ iFirstDayOfWeek = CalendarUtils.getWeekConfigurationValues(vCalendarWeekParameter, this.oLocale).firstDayOfWeek;
2202
+ }
2071
2203
  var iDayNumberOfWeek = iDayOfWeek - (iFirstDayOfWeek - 1);
2072
2204
  if (iDayNumberOfWeek <= 0) {
2073
2205
  iDayNumberOfWeek += 7;
@@ -2133,4 +2265,28 @@ DateFormat.prototype.getAllowedCharacters = function (aFormatArray) {
2133
2265
  }
2134
2266
  return sAllowedCharacters;
2135
2267
  };
2268
+ DateFormat.prototype.getPlaceholderText = function () {
2269
+ var oResourceBundle = Core.getLibraryResourceBundle();
2270
+ return oResourceBundle.getText('date.placeholder', [this.format.apply(this, this.getSampleValue())]);
2271
+ };
2272
+ DateFormat.prototype.getSampleValue = function () {
2273
+ var oDate, iFullYear = UI5Date.getInstance().getFullYear(), bUTC = this.oFormatOptions.UTC;
2274
+ function getDate(iYear, iMonth, iDay, iHours, iMinutes, iSeconds, iMilliseconds) {
2275
+ return bUTC ? UI5Date.getInstance(Date.UTC(iYear, iMonth, iDay, iHours, iMinutes, iSeconds, iMilliseconds)) : UI5Date.getInstance(iYear, iMonth, iDay, iHours, iMinutes, iSeconds, iMilliseconds);
2276
+ }
2277
+ oDate = getDate(iFullYear, 11, 31, 23, 59, 58, 123);
2278
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
2279
+ return [
2280
+ oDate,
2281
+ Configuration.getTimezone()
2282
+ ];
2283
+ }
2284
+ if (this.oFormatOptions.interval) {
2285
+ return [[
2286
+ getDate(iFullYear, 11, 22, 9, 12, 34, 567),
2287
+ oDate
2288
+ ]];
2289
+ }
2290
+ return [oDate];
2291
+ };
2136
2292
  export default DateFormat;