@ui5/webcomponents-localization 0.0.0-dff5837d7 → 0.0.0-e55c2cec6

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 (204) hide show
  1. package/.eslintignore +1 -0
  2. package/CHANGELOG.md +260 -0
  3. package/README.md +36 -6
  4. package/dist/Assets-static.d.ts +1 -0
  5. package/dist/Assets-static.js +3 -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 +41 -0
  17. package/dist/dates/CalendarDate.js +170 -181
  18. package/dist/dates/CalendarDate.js.map +1 -0
  19. package/dist/dates/ExtremeDates.d.ts +5 -0
  20. package/dist/dates/ExtremeDates.js +29 -0
  21. package/dist/dates/ExtremeDates.js.map +1 -0
  22. package/dist/dates/UniversalDate.d.ts +46 -0
  23. package/dist/dates/UniversalDate.js +5 -0
  24. package/dist/dates/UniversalDate.js.map +1 -0
  25. package/dist/dates/calculateWeekNumber.d.ts +4 -0
  26. package/dist/dates/calculateWeekNumber.js +42 -48
  27. package/dist/dates/calculateWeekNumber.js.map +1 -0
  28. package/dist/dates/convertMonthNumbersToMonthNames.d.ts +16 -0
  29. package/dist/dates/convertMonthNumbersToMonthNames.js +30 -0
  30. package/dist/dates/convertMonthNumbersToMonthNames.js.map +1 -0
  31. package/dist/dates/getDaysInMonth.d.ts +3 -0
  32. package/dist/dates/getDaysInMonth.js +10 -0
  33. package/dist/dates/getDaysInMonth.js.map +1 -0
  34. package/dist/dates/getRoundedTimestamp.d.ts +7 -0
  35. package/dist/dates/getRoundedTimestamp.js +14 -0
  36. package/dist/dates/getRoundedTimestamp.js.map +1 -0
  37. package/dist/dates/getTodayUTCTimestamp.d.ts +7 -0
  38. package/dist/dates/getTodayUTCTimestamp.js +8 -0
  39. package/dist/dates/getTodayUTCTimestamp.js.map +1 -0
  40. package/dist/dates/modifyDateBy.d.ts +13 -0
  41. package/dist/dates/modifyDateBy.js +40 -0
  42. package/dist/dates/modifyDateBy.js.map +1 -0
  43. package/dist/dates/transformDateToSecondaryType.d.ts +7 -0
  44. package/dist/dates/transformDateToSecondaryType.js +17 -0
  45. package/dist/dates/transformDateToSecondaryType.js.map +1 -0
  46. package/{src/features/calendar/Buddhist.js → dist/features/calendar/Buddhist.d.ts} +0 -0
  47. package/dist/features/calendar/Buddhist.js +1 -0
  48. package/dist/features/calendar/Buddhist.js.map +1 -0
  49. package/{src/features/calendar/Gregorian.js → dist/features/calendar/Gregorian.d.ts} +0 -0
  50. package/dist/features/calendar/Gregorian.js +1 -0
  51. package/dist/features/calendar/Gregorian.js.map +1 -0
  52. package/{src/features/calendar/Islamic.js → dist/features/calendar/Islamic.d.ts} +0 -0
  53. package/dist/features/calendar/Islamic.js +1 -0
  54. package/dist/features/calendar/Islamic.js.map +1 -0
  55. package/{src/features/calendar/Japanese.js → dist/features/calendar/Japanese.d.ts} +0 -0
  56. package/dist/features/calendar/Japanese.js +1 -0
  57. package/dist/features/calendar/Japanese.js.map +1 -0
  58. package/{src/features/calendar/Persian.js → dist/features/calendar/Persian.d.ts} +0 -0
  59. package/dist/features/calendar/Persian.js +1 -0
  60. package/dist/features/calendar/Persian.js.map +1 -0
  61. package/dist/generated/assets/cldr/ar.json +803 -3
  62. package/dist/generated/assets/cldr/ar_EG.json +803 -3
  63. package/dist/generated/assets/cldr/ar_SA.json +803 -3
  64. package/dist/generated/assets/cldr/bg.json +768 -3
  65. package/dist/generated/assets/cldr/ca.json +802 -3
  66. package/dist/generated/assets/cldr/cs.json +801 -3
  67. package/dist/generated/assets/cldr/cy.json +6614 -0
  68. package/dist/generated/assets/cldr/da.json +768 -3
  69. package/dist/generated/assets/cldr/de.json +802 -3
  70. package/dist/generated/assets/cldr/de_AT.json +802 -3
  71. package/dist/generated/assets/cldr/de_CH.json +802 -3
  72. package/dist/generated/assets/cldr/el.json +701 -3
  73. package/dist/generated/assets/cldr/el_CY.json +701 -3
  74. package/dist/generated/assets/cldr/en.json +767 -3
  75. package/dist/generated/assets/cldr/en_AU.json +768 -4
  76. package/dist/generated/assets/cldr/en_GB.json +767 -3
  77. package/dist/generated/assets/cldr/en_HK.json +767 -3
  78. package/dist/generated/assets/cldr/en_IE.json +767 -3
  79. package/dist/generated/assets/cldr/en_IN.json +767 -3
  80. package/dist/generated/assets/cldr/en_NZ.json +767 -3
  81. package/dist/generated/assets/cldr/en_PG.json +767 -3
  82. package/dist/generated/assets/cldr/en_SG.json +767 -3
  83. package/dist/generated/assets/cldr/en_ZA.json +767 -3
  84. package/dist/generated/assets/cldr/es.json +734 -3
  85. package/dist/generated/assets/cldr/es_AR.json +734 -3
  86. package/dist/generated/assets/cldr/es_BO.json +737 -6
  87. package/dist/generated/assets/cldr/es_CL.json +737 -6
  88. package/dist/generated/assets/cldr/es_CO.json +734 -3
  89. package/dist/generated/assets/cldr/es_MX.json +737 -6
  90. package/dist/generated/assets/cldr/es_PE.json +737 -6
  91. package/dist/generated/assets/cldr/es_UY.json +737 -6
  92. package/dist/generated/assets/cldr/es_VE.json +736 -5
  93. package/dist/generated/assets/cldr/et.json +767 -3
  94. package/dist/generated/assets/cldr/fa.json +769 -3
  95. package/dist/generated/assets/cldr/fi.json +801 -3
  96. package/dist/generated/assets/cldr/fr.json +767 -3
  97. package/dist/generated/assets/cldr/fr_BE.json +767 -3
  98. package/dist/generated/assets/cldr/fr_CA.json +767 -3
  99. package/dist/generated/assets/cldr/fr_CH.json +767 -3
  100. package/dist/generated/assets/cldr/fr_LU.json +767 -3
  101. package/dist/generated/assets/cldr/he.json +802 -3
  102. package/dist/generated/assets/cldr/hi.json +734 -3
  103. package/dist/generated/assets/cldr/hr.json +767 -3
  104. package/dist/generated/assets/cldr/hu.json +835 -3
  105. package/dist/generated/assets/cldr/id.json +767 -3
  106. package/dist/generated/assets/cldr/it.json +767 -3
  107. package/dist/generated/assets/cldr/it_CH.json +767 -3
  108. package/dist/generated/assets/cldr/ja.json +801 -3
  109. package/dist/generated/assets/cldr/kk.json +767 -3
  110. package/dist/generated/assets/cldr/ko.json +801 -3
  111. package/dist/generated/assets/cldr/lt.json +767 -3
  112. package/dist/generated/assets/cldr/lv.json +767 -3
  113. package/dist/generated/assets/cldr/ms.json +735 -3
  114. package/dist/generated/assets/cldr/nb.json +768 -3
  115. package/dist/generated/assets/cldr/nl.json +734 -3
  116. package/dist/generated/assets/cldr/nl_BE.json +734 -3
  117. package/dist/generated/assets/cldr/pl.json +801 -3
  118. package/dist/generated/assets/cldr/pt.json +767 -3
  119. package/dist/generated/assets/cldr/pt_PT.json +767 -3
  120. package/dist/generated/assets/cldr/ro.json +767 -3
  121. package/dist/generated/assets/cldr/ru.json +767 -3
  122. package/dist/generated/assets/cldr/ru_UA.json +767 -3
  123. package/dist/generated/assets/cldr/sk.json +801 -3
  124. package/dist/generated/assets/cldr/sl.json +801 -3
  125. package/dist/generated/assets/cldr/sr.json +767 -3
  126. package/dist/generated/assets/cldr/sr_Latn.json +5891 -0
  127. package/dist/generated/assets/cldr/sv.json +768 -3
  128. package/dist/generated/assets/cldr/th.json +835 -3
  129. package/dist/generated/assets/cldr/tr.json +835 -3
  130. package/dist/generated/assets/cldr/uk.json +767 -3
  131. package/dist/generated/assets/cldr/vi.json +767 -3
  132. package/dist/generated/assets/cldr/zh_CN.json +803 -4
  133. package/dist/generated/assets/cldr/zh_HK.json +803 -4
  134. package/dist/generated/assets/cldr/zh_SG.json +803 -4
  135. package/dist/generated/assets/cldr/zh_TW.json +802 -3
  136. package/dist/generated/json-imports/LocaleData-static.js +90 -0
  137. package/dist/generated/json-imports/LocaleData.js +88 -91
  138. package/dist/getCachedLocaleDataInstance.d.ts +4 -0
  139. package/dist/getCachedLocaleDataInstance.js +10 -0
  140. package/dist/getCachedLocaleDataInstance.js.map +1 -0
  141. package/dist/locale/getLocaleData.d.ts +11 -0
  142. package/dist/locale/getLocaleData.js +13 -17
  143. package/dist/locale/getLocaleData.js.map +1 -0
  144. package/dist/sap/base/Log.js +28 -37
  145. package/dist/sap/base/assert.js +5 -10
  146. package/dist/sap/base/util/LoaderExtensions.d.ts +4 -0
  147. package/dist/sap/base/util/LoaderExtensions.js +11 -4
  148. package/dist/sap/base/util/LoaderExtensions.js.map +1 -0
  149. package/dist/sap/base/util/array/uniqueSort.js +7 -7
  150. package/dist/sap/base/util/deepEqual.js +1 -5
  151. package/dist/sap/ui/base/Interface.js +3 -5
  152. package/dist/sap/ui/base/Metadata.js +1 -3
  153. package/dist/sap/ui/base/Object.js +26 -2
  154. package/dist/sap/ui/core/Configuration.d.ts +17 -0
  155. package/dist/sap/ui/core/Configuration.js +20 -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 -32
  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 +13 -0
  162. package/dist/sap/ui/core/FormatSettings.js.map +1 -0
  163. package/dist/sap/ui/core/Locale.js +70 -31
  164. package/dist/sap/ui/core/LocaleData.js +133 -1506
  165. package/dist/sap/ui/core/date/Buddhist.js +0 -6
  166. package/dist/sap/ui/core/date/CalendarUtils.js +36 -0
  167. package/dist/sap/ui/core/date/CalendarWeekNumbering.js +7 -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/UniversalDate.js +82 -23
  171. package/dist/sap/ui/core/format/DateFormat.js +530 -222
  172. package/dist/sap/ui/core/format/TimezoneUtil.js +94 -0
  173. package/package-scripts.js +14 -7
  174. package/package.json +13 -14
  175. package/src/Assets-static.ts +2 -0
  176. package/src/{Assets.js → Assets.ts} +0 -0
  177. package/src/DateFormat.ts +8 -0
  178. package/src/LocaleData.ts +8 -0
  179. package/src/dates/{CalendarDate.js → CalendarDate.ts} +64 -35
  180. package/src/dates/ExtremeDates.ts +40 -0
  181. package/src/dates/UniversalDate.ts +51 -0
  182. package/src/dates/{calculateWeekNumber.js → calculateWeekNumber.ts} +5 -3
  183. package/src/dates/convertMonthNumbersToMonthNames.ts +34 -0
  184. package/src/dates/getDaysInMonth.ts +11 -0
  185. package/src/dates/getRoundedTimestamp.ts +14 -0
  186. package/src/dates/getTodayUTCTimestamp.ts +10 -0
  187. package/src/dates/modifyDateBy.ts +42 -0
  188. package/src/dates/transformDateToSecondaryType.ts +21 -0
  189. package/src/features/calendar/Buddhist.ts +1 -0
  190. package/src/features/calendar/Gregorian.ts +1 -0
  191. package/src/features/calendar/Islamic.ts +1 -0
  192. package/src/features/calendar/Japanese.ts +1 -0
  193. package/src/features/calendar/Persian.ts +1 -0
  194. package/src/getCachedLocaleDataInstance.ts +15 -0
  195. package/src/locale/{getLocaleData.js → getLocaleData.ts} +9 -8
  196. package/src/sap/base/util/LoaderExtensions.ts +17 -0
  197. package/src/sap/ui/core/{Core.js → Configuration.ts} +5 -21
  198. package/src/sap/ui/core/Core.ts +15 -0
  199. package/src/sap/ui/core/FormatSettings.ts +15 -0
  200. package/tsconfig.json +13 -0
  201. package/used-modules.txt +4 -1
  202. package/src/DateFormat.js +0 -3
  203. package/src/LocaleData.js +0 -3
  204. package/src/sap/base/util/LoaderExtensions.js +0 -7
@@ -1,17 +1,32 @@
1
- import Core from '../Core.js';
2
1
  import CalendarType from '../CalendarType.js';
3
2
  import Locale from '../Locale.js';
4
3
  import LocaleData from '../LocaleData.js';
5
4
  import UniversalDate from '../date/UniversalDate.js';
5
+ import CalendarUtils from '../date/CalendarUtils.js';
6
+ import CalendarWeekNumbering from '../date/CalendarWeekNumbering.js';
7
+ import TimezoneUtil from './TimezoneUtil.js';
6
8
  import deepEqual from '../../../base/util/deepEqual.js';
7
9
  import formatMessage from '../../../base/strings/formatMessage.js';
8
10
  import Log from '../../../base/Log.js';
9
11
  import extend from '../../../base/util/extend.js';
12
+ import Configuration from '../Configuration.js';
10
13
  var DateFormat = function () {
11
14
  throw new Error();
12
15
  };
16
+ var mDateFormatTypes = {
17
+ DATE: 'date',
18
+ TIME: 'time',
19
+ DATETIME: 'datetime',
20
+ DATETIME_WITH_TIMEZONE: 'datetimeWithTimezone'
21
+ };
13
22
  var mCldrDatePattern = {};
23
+ var checkTimezoneParameterType = function (sTimezone) {
24
+ if (typeof sTimezone !== 'string' && !(sTimezone instanceof String) && sTimezone != null) {
25
+ throw new TypeError('The given timezone must be a string.');
26
+ }
27
+ };
14
28
  DateFormat.oDateInfo = {
29
+ type: mDateFormatTypes.DATE,
15
30
  oDefaultFormatOptions: {
16
31
  style: 'medium',
17
32
  relativeScale: 'day',
@@ -64,6 +79,7 @@ DateFormat.oDateInfo = {
64
79
  ]
65
80
  };
66
81
  DateFormat.oDateTimeInfo = {
82
+ type: mDateFormatTypes.DATETIME,
67
83
  oDefaultFormatOptions: {
68
84
  style: 'medium',
69
85
  relativeScale: 'auto',
@@ -126,7 +142,41 @@ DateFormat.oDateTimeInfo = {
126
142
  'Seconds'
127
143
  ]
128
144
  };
145
+ DateFormat._getDateTimeWithTimezoneInfo = function (oFormatOptions) {
146
+ var bShowDate = oFormatOptions.showDate === undefined || oFormatOptions.showDate;
147
+ var bShowTime = oFormatOptions.showTime === undefined || oFormatOptions.showTime;
148
+ var bShowTimezone = oFormatOptions.showTimezone === undefined || oFormatOptions.showTimezone;
149
+ var oBaselineType = DateFormat.oDateTimeInfo;
150
+ if (bShowDate && !bShowTime) {
151
+ oBaselineType = DateFormat.oDateInfo;
152
+ } else if (!bShowDate && bShowTime) {
153
+ oBaselineType = DateFormat.oTimeInfo;
154
+ }
155
+ return Object.assign({}, oBaselineType, {
156
+ type: mDateFormatTypes.DATETIME_WITH_TIMEZONE,
157
+ getTimezonePattern: function (sPattern) {
158
+ if (!bShowDate && !bShowTime && bShowTimezone) {
159
+ return 'VV';
160
+ } else if (!bShowTimezone) {
161
+ return sPattern;
162
+ } else {
163
+ return sPattern + ' VV';
164
+ }
165
+ },
166
+ getPattern: function (oLocaleData, sStyle, sCalendarType) {
167
+ if (!bShowDate && !bShowTime && bShowTimezone) {
168
+ return 'VV';
169
+ }
170
+ if (!bShowTimezone) {
171
+ return oBaselineType.getPattern(oLocaleData, sStyle, sCalendarType);
172
+ }
173
+ var sPattern = oBaselineType.getPattern(oLocaleData, sStyle, sCalendarType);
174
+ return oLocaleData.applyTimezonePattern(sPattern);
175
+ }
176
+ });
177
+ };
129
178
  DateFormat.oTimeInfo = {
179
+ type: mDateFormatTypes.TIME,
130
180
  oDefaultFormatOptions: {
131
181
  style: 'medium',
132
182
  relativeScale: 'auto',
@@ -179,6 +229,27 @@ DateFormat.getDateInstance = function (oFormatOptions, oLocale) {
179
229
  DateFormat.getDateTimeInstance = function (oFormatOptions, oLocale) {
180
230
  return this.createInstance(oFormatOptions, oLocale, this.oDateTimeInfo);
181
231
  };
232
+ DateFormat.getDateTimeWithTimezoneInstance = function (oFormatOptions, oLocale) {
233
+ if (oFormatOptions && !(oFormatOptions instanceof Locale)) {
234
+ oFormatOptions = Object.assign({}, oFormatOptions);
235
+ if (typeof oFormatOptions.showTimezone === 'string') {
236
+ var sShowTimezone = oFormatOptions.showTimezone;
237
+ if (oFormatOptions.showDate === undefined && oFormatOptions.showTime === undefined) {
238
+ if (sShowTimezone === 'Hide') {
239
+ oFormatOptions.showTimezone = false;
240
+ } else if (sShowTimezone === 'Only') {
241
+ oFormatOptions.showDate = false;
242
+ oFormatOptions.showTime = false;
243
+ }
244
+ }
245
+ oFormatOptions.showTimezone = sShowTimezone !== 'Hide';
246
+ }
247
+ if (oFormatOptions.showDate === false && oFormatOptions.showTime === false && oFormatOptions.showTimezone === false) {
248
+ throw new TypeError('Invalid Configuration. One of the following format options must be true: showDate, showTime or showTimezone.');
249
+ }
250
+ }
251
+ return this.createInstance(oFormatOptions, oLocale, DateFormat._getDateTimeWithTimezoneInfo(oFormatOptions || {}));
252
+ };
182
253
  DateFormat.getTimeInstance = function (oFormatOptions, oLocale) {
183
254
  return this.createInstance(oFormatOptions, oLocale, this.oTimeInfo);
184
255
  };
@@ -194,13 +265,29 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
194
265
  oFormatOptions = undefined;
195
266
  }
196
267
  if (!oLocale) {
197
- oLocale = Core.getConfiguration().getFormatSettings().getFormatLocale();
268
+ oLocale = Configuration.getFormatSettings().getFormatLocale();
198
269
  }
199
270
  oFormat.oLocale = oLocale;
200
271
  oFormat.oLocaleData = LocaleData.getInstance(oLocale);
201
272
  oFormat.oFormatOptions = extend({}, oInfo.oDefaultFormatOptions, oFormatOptions);
273
+ if (oInfo.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
274
+ oFormat.oFormatOptions.interval = false;
275
+ oFormat.oFormatOptions.singleIntervalValue = false;
276
+ oFormat.oFormatOptions.UTC = false;
277
+ } else {
278
+ oFormat.oFormatOptions.showTimezone = undefined;
279
+ oFormat.oFormatOptions.showDate = undefined;
280
+ oFormat.oFormatOptions.showTime = undefined;
281
+ }
282
+ oFormat.type = oInfo.type;
202
283
  if (!oFormat.oFormatOptions.calendarType) {
203
- oFormat.oFormatOptions.calendarType = Core.getConfiguration().getCalendarType();
284
+ oFormat.oFormatOptions.calendarType = Configuration.getCalendarType();
285
+ }
286
+ if (oFormat.oFormatOptions.firstDayOfWeek === undefined && oFormat.oFormatOptions.minimalDaysInFirstWeek !== undefined || oFormat.oFormatOptions.firstDayOfWeek !== undefined && oFormat.oFormatOptions.minimalDaysInFirstWeek === undefined) {
287
+ throw new TypeError('Format options firstDayOfWeek and minimalDaysInFirstWeek need both to be set, but only one was provided.');
288
+ }
289
+ if (oFormat.oFormatOptions.calendarWeekNumbering && !Object.values(CalendarWeekNumbering).includes(oFormat.oFormatOptions.calendarWeekNumbering)) {
290
+ throw new TypeError('Illegal format option calendarWeekNumbering: \'' + oFormat.oFormatOptions.calendarWeekNumbering + '\'');
204
291
  }
205
292
  if (!oFormat.oFormatOptions.pattern) {
206
293
  if (oFormat.oFormatOptions.format) {
@@ -246,7 +333,7 @@ DateFormat.createInstance = function (oFormatOptions, oLocale, oInfo) {
246
333
  if (oFormat.oFormatOptions.pattern && oInfo.bPatternFallbackWithoutDelimiter) {
247
334
  aFallbackFormatOptions = DateFormat._createFallbackOptionsWithoutDelimiter(oFormat.oFormatOptions.pattern).concat(aFallbackFormatOptions);
248
335
  }
249
- oFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, sCalendarType, oLocale, oInfo, oFormat.oFormatOptions.interval);
336
+ oFallbackFormats = DateFormat._createFallbackFormat(aFallbackFormatOptions, sCalendarType, oLocale, oInfo, oFormat.oFormatOptions);
250
337
  }
251
338
  oFormat.aFallbackFormats = oFallbackFormats;
252
339
  }
@@ -282,14 +369,28 @@ DateFormat.prototype.init = function () {
282
369
  this.aErasNarrow = this.oLocaleData.getEras('narrow', sCalendarType);
283
370
  this.aErasAbbrev = this.oLocaleData.getEras('abbreviated', sCalendarType);
284
371
  this.aErasWide = this.oLocaleData.getEras('wide', sCalendarType);
285
- this.aDayPeriods = this.oLocaleData.getDayPeriods('abbreviated', sCalendarType);
372
+ this.aDayPeriodsAbbrev = this.oLocaleData.getDayPeriods('abbreviated', sCalendarType);
373
+ this.aDayPeriodsNarrow = this.oLocaleData.getDayPeriods('narrow', sCalendarType);
374
+ this.aDayPeriodsWide = this.oLocaleData.getDayPeriods('wide', sCalendarType);
375
+ this.oFlexibleDayPeriodsAbbrev = this.oLocaleData.getFlexibleDayPeriods('abbreviated', sCalendarType);
376
+ this.oFlexibleDayPeriodsNarrow = this.oLocaleData.getFlexibleDayPeriods('narrow', sCalendarType);
377
+ this.oFlexibleDayPeriodsWide = this.oLocaleData.getFlexibleDayPeriods('wide', sCalendarType);
378
+ this.oFlexibleDayPeriodsAbbrevSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('abbreviated', sCalendarType);
379
+ this.oFlexibleDayPeriodsNarrowSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('narrow', sCalendarType);
380
+ this.oFlexibleDayPeriodsWideSt = this.oLocaleData.getFlexibleDayPeriodsStandAlone('wide', sCalendarType);
286
381
  this.aFormatArray = this.parseCldrDatePattern(this.oFormatOptions.pattern);
287
382
  this.sAllowedCharacters = this.getAllowedCharacters(this.aFormatArray);
288
383
  };
289
- DateFormat._createFallbackFormat = function (aFallbackFormatOptions, sCalendarType, oLocale, oInfo, bInterval) {
384
+ DateFormat._createFallbackFormat = function (aFallbackFormatOptions, sCalendarType, oLocale, oInfo, oParentFormatOptions) {
290
385
  return aFallbackFormatOptions.map(function (oOptions) {
291
386
  var oFormatOptions = Object.assign({}, oOptions);
292
- if (bInterval) {
387
+ oFormatOptions.showDate = oParentFormatOptions.showDate;
388
+ oFormatOptions.showTime = oParentFormatOptions.showTime;
389
+ oFormatOptions.showTimezone = oParentFormatOptions.showTimezone;
390
+ if (typeof oInfo.getTimezonePattern === 'function' && oFormatOptions.pattern) {
391
+ oFormatOptions.pattern = oInfo.getTimezonePattern(oFormatOptions.pattern);
392
+ }
393
+ if (oParentFormatOptions.interval) {
293
394
  oFormatOptions.interval = true;
294
395
  }
295
396
  oFormatOptions.calendarType = sCalendarType;
@@ -337,20 +438,35 @@ var oParseHelper = {
337
438
  }
338
439
  return sValue.substr(0, iLength);
339
440
  },
340
- findEntry: function (sValue, aList) {
441
+ startsWithIgnoreCase: function (sValue, sSubstring, sLocale) {
442
+ if (sValue.startsWith(sSubstring)) {
443
+ return true;
444
+ }
445
+ try {
446
+ var sSubToLocaleUpperCase = sSubstring.toLocaleUpperCase(sLocale);
447
+ var sValueUpperCase = sValue.toLocaleUpperCase(sLocale);
448
+ if (sSubToLocaleUpperCase.length !== sSubstring.length || sValueUpperCase.length !== sValue.length) {
449
+ return false;
450
+ }
451
+ return sValueUpperCase.startsWith(sSubToLocaleUpperCase);
452
+ } catch (e) {
453
+ return false;
454
+ }
455
+ },
456
+ findEntry: function (sValue, aList, sLocale) {
341
457
  var iFoundIndex = -1, iMatchedLength = 0;
342
458
  for (var j = 0; j < aList.length; j++) {
343
- if (aList[j] && aList[j].length > iMatchedLength && sValue.indexOf(aList[j]) === 0) {
459
+ if (aList[j] && aList[j].length > iMatchedLength && this.startsWithIgnoreCase(sValue, aList[j], sLocale)) {
344
460
  iFoundIndex = j;
345
461
  iMatchedLength = aList[j].length;
346
462
  }
347
463
  }
348
464
  return {
349
465
  index: iFoundIndex,
350
- value: iFoundIndex === -1 ? null : aList[iFoundIndex]
466
+ length: iMatchedLength
351
467
  };
352
468
  },
353
- parseTZ: function (sValue, bISO) {
469
+ parseTZ: function (sValue, bColonSeparated) {
354
470
  var iLength = 0;
355
471
  var iTZFactor = sValue.charAt(0) == '+' ? -1 : 1;
356
472
  var sPart;
@@ -358,15 +474,18 @@ var oParseHelper = {
358
474
  sPart = this.findNumbers(sValue.substr(iLength), 2);
359
475
  var iTZDiffHour = parseInt(sPart);
360
476
  iLength += 2;
361
- if (bISO) {
477
+ if (bColonSeparated) {
362
478
  iLength++;
363
479
  }
364
480
  sPart = this.findNumbers(sValue.substr(iLength), 2);
365
- iLength += 2;
366
- var iTZDiff = parseInt(sPart);
481
+ var iTZDiff = 0;
482
+ if (sPart) {
483
+ iLength += 2;
484
+ iTZDiff = parseInt(sPart);
485
+ }
367
486
  return {
368
487
  length: iLength,
369
- tzDiff: (iTZDiff + 60 * iTZDiffHour) * iTZFactor
488
+ tzDiff: (iTZDiff + 60 * iTZDiffHour) * 60 * iTZFactor
370
489
  };
371
490
  },
372
491
  checkValid: function (sType, bPartInvalid, oFormat) {
@@ -378,7 +497,7 @@ var oParseHelper = {
378
497
  DateFormat.prototype.oSymbols = {
379
498
  '': {
380
499
  name: 'text',
381
- format: function (oField, oDate, bUTC, oFormat) {
500
+ format: function (oField, oDate) {
382
501
  return oField.value;
383
502
  },
384
503
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -422,7 +541,7 @@ DateFormat.prototype.oSymbols = {
422
541
  'G': {
423
542
  name: 'era',
424
543
  format: function (oField, oDate, bUTC, oFormat) {
425
- var iEra = bUTC ? oDate.getUTCEra() : oDate.getEra();
544
+ var iEra = oDate.getUTCEra();
426
545
  if (oField.digits <= 3) {
427
546
  return oFormat.aErasAbbrev[iEra];
428
547
  } else if (oField.digits === 4) {
@@ -439,11 +558,11 @@ DateFormat.prototype.oSymbols = {
439
558
  ];
440
559
  for (var i = 0; i < aErasVariants.length; i++) {
441
560
  var aVariants = aErasVariants[i];
442
- var oFound = oParseHelper.findEntry(sValue, aVariants);
561
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
443
562
  if (oFound.index !== -1) {
444
563
  return {
445
564
  era: oFound.index,
446
- length: oFound.value.length
565
+ length: oFound.length
447
566
  };
448
567
  }
449
568
  }
@@ -456,7 +575,7 @@ DateFormat.prototype.oSymbols = {
456
575
  'y': {
457
576
  name: 'year',
458
577
  format: function (oField, oDate, bUTC, oFormat) {
459
- var iYear = bUTC ? oDate.getUTCFullYear() : oDate.getFullYear();
578
+ var iYear = oDate.getUTCFullYear();
460
579
  var sYear = String(iYear);
461
580
  var sCalendarType = oFormat.oFormatOptions.calendarType;
462
581
  if (oField.digits == 2 && sYear.length > 2) {
@@ -479,7 +598,7 @@ DateFormat.prototype.oSymbols = {
479
598
  }
480
599
  var iYear = parseInt(sPart);
481
600
  if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
482
- var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType), iCurrentYear = oCurrentDate.getFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iYear - iCurrentYear;
601
+ var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iYear - iCurrentYear;
483
602
  if (iYearDiff < -70) {
484
603
  iYear += (iCurrentCentury + 1) * 100;
485
604
  } else if (iYearDiff < 30) {
@@ -498,7 +617,7 @@ DateFormat.prototype.oSymbols = {
498
617
  'Y': {
499
618
  name: 'weekYear',
500
619
  format: function (oField, oDate, bUTC, oFormat) {
501
- var oWeek = bUTC ? oDate.getUTCWeek() : oDate.getWeek();
620
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
502
621
  var iWeekYear = oWeek.year;
503
622
  var sWeekYear = String(iWeekYear);
504
623
  var sCalendarType = oFormat.oFormatOptions.calendarType;
@@ -521,9 +640,9 @@ DateFormat.prototype.oSymbols = {
521
640
  sPart = oParseHelper.findNumbers(sValue, oPart.digits);
522
641
  }
523
642
  var iYear = parseInt(sPart);
524
- var iWeekYear;
643
+ var iWeekYear = iYear;
525
644
  if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
526
- var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType), iCurrentYear = oCurrentDate.getFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iWeekYear - iCurrentYear;
645
+ var oCurrentDate = UniversalDate.getInstance(new Date(), sCalendarType), iCurrentYear = oCurrentDate.getUTCFullYear(), iCurrentCentury = Math.floor(iCurrentYear / 100), iYearDiff = iCurrentCentury * 100 + iWeekYear - iCurrentYear;
527
646
  if (iYearDiff < -70) {
528
647
  iWeekYear += (iCurrentCentury + 1) * 100;
529
648
  } else if (iYearDiff < 30) {
@@ -543,7 +662,7 @@ DateFormat.prototype.oSymbols = {
543
662
  'M': {
544
663
  name: 'month',
545
664
  format: function (oField, oDate, bUTC, oFormat) {
546
- var iMonth = bUTC ? oDate.getUTCMonth() : oDate.getMonth();
665
+ var iMonth = oDate.getUTCMonth();
547
666
  if (oField.digits == 3) {
548
667
  return oFormat.aMonthsAbbrev[iMonth];
549
668
  } else if (oField.digits == 4) {
@@ -576,11 +695,11 @@ DateFormat.prototype.oSymbols = {
576
695
  } else {
577
696
  for (var i = 0; i < aMonthsVariants.length; i++) {
578
697
  var aVariants = aMonthsVariants[i];
579
- var oFound = oParseHelper.findEntry(sValue, aVariants);
698
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
580
699
  if (oFound.index !== -1) {
581
700
  return {
582
701
  month: oFound.index,
583
- length: oFound.value.length
702
+ length: oFound.length
584
703
  };
585
704
  }
586
705
  }
@@ -596,7 +715,7 @@ DateFormat.prototype.oSymbols = {
596
715
  'L': {
597
716
  name: 'monthStandalone',
598
717
  format: function (oField, oDate, bUTC, oFormat) {
599
- var iMonth = bUTC ? oDate.getUTCMonth() : oDate.getMonth();
718
+ var iMonth = oDate.getUTCMonth();
600
719
  if (oField.digits == 3) {
601
720
  return oFormat.aMonthsAbbrevSt[iMonth];
602
721
  } else if (oField.digits == 4) {
@@ -629,11 +748,11 @@ DateFormat.prototype.oSymbols = {
629
748
  } else {
630
749
  for (var i = 0; i < aMonthsVariants.length; i++) {
631
750
  var aVariants = aMonthsVariants[i];
632
- var oFound = oParseHelper.findEntry(sValue, aVariants);
751
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
633
752
  if (oFound.index !== -1) {
634
753
  return {
635
754
  month: oFound.index,
636
- length: oFound.value.length
755
+ length: oFound.length
637
756
  };
638
757
  }
639
758
  }
@@ -649,7 +768,7 @@ DateFormat.prototype.oSymbols = {
649
768
  'w': {
650
769
  name: 'weekInYear',
651
770
  format: function (oField, oDate, bUTC, oFormat) {
652
- var oWeek = bUTC ? oDate.getUTCWeek() : oDate.getWeek();
771
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
653
772
  var iWeek = oWeek.week;
654
773
  var sWeek = String(iWeek + 1);
655
774
  if (oField.digits < 3) {
@@ -671,11 +790,11 @@ DateFormat.prototype.oSymbols = {
671
790
  bValid = oParseHelper.checkValid(oPart.type, !sPart, oFormat);
672
791
  } else {
673
792
  sPart = oFormat.oLocaleData.getCalendarWeek(oPart.digits === 3 ? 'narrow' : 'wide');
674
- sPart = sPart.replace('{0}', '[0-9]+');
793
+ sPart = sPart.replace('{0}', '([0-9]+)');
675
794
  var rWeekNumber = new RegExp(sPart), oResult = rWeekNumber.exec(sValue);
676
795
  if (oResult) {
677
796
  iLength = oResult[0].length;
678
- iWeek = parseInt(oResult[0]) - 1;
797
+ iWeek = parseInt(oResult[oResult.length - 1]) - 1;
679
798
  } else {
680
799
  bValid = oParseHelper.checkValid(oPart.type, true, oFormat);
681
800
  }
@@ -689,7 +808,7 @@ DateFormat.prototype.oSymbols = {
689
808
  },
690
809
  'W': {
691
810
  name: 'weekInMonth',
692
- format: function (oField, oDate, bUTC, oFormat) {
811
+ format: function (oField, oDate) {
693
812
  return '';
694
813
  },
695
814
  parse: function () {
@@ -698,7 +817,7 @@ DateFormat.prototype.oSymbols = {
698
817
  },
699
818
  'D': {
700
819
  name: 'dayInYear',
701
- format: function (oField, oDate, bUTC, oFormat) {
820
+ format: function (oField, oDate) {
702
821
  },
703
822
  parse: function () {
704
823
  return {};
@@ -706,8 +825,8 @@ DateFormat.prototype.oSymbols = {
706
825
  },
707
826
  'd': {
708
827
  name: 'day',
709
- format: function (oField, oDate, bUTC, oFormat) {
710
- var iDate = bUTC ? oDate.getUTCDate() : oDate.getDate();
828
+ format: function (oField, oDate) {
829
+ var iDate = oDate.getUTCDate();
711
830
  return String(iDate).padStart(oField.digits, '0');
712
831
  },
713
832
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -727,7 +846,7 @@ DateFormat.prototype.oSymbols = {
727
846
  'Q': {
728
847
  name: 'quarter',
729
848
  format: function (oField, oDate, bUTC, oFormat) {
730
- var iQuarter = bUTC ? oDate.getUTCQuarter() : oDate.getQuarter();
849
+ var iQuarter = oDate.getUTCQuarter();
731
850
  if (oField.digits == 3) {
732
851
  return oFormat.aQuartersAbbrev[iQuarter];
733
852
  } else if (oField.digits == 4) {
@@ -760,11 +879,11 @@ DateFormat.prototype.oSymbols = {
760
879
  } else {
761
880
  for (var i = 0; i < aQuartersVariants.length; i++) {
762
881
  var aVariants = aQuartersVariants[i];
763
- var oFound = oParseHelper.findEntry(sValue, aVariants);
882
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
764
883
  if (oFound.index !== -1) {
765
884
  return {
766
885
  quarter: oFound.index,
767
- length: oFound.value.length
886
+ length: oFound.length
768
887
  };
769
888
  }
770
889
  }
@@ -780,7 +899,7 @@ DateFormat.prototype.oSymbols = {
780
899
  'q': {
781
900
  name: 'quarterStandalone',
782
901
  format: function (oField, oDate, bUTC, oFormat) {
783
- var iQuarter = bUTC ? oDate.getUTCQuarter() : oDate.getQuarter();
902
+ var iQuarter = oDate.getUTCQuarter();
784
903
  if (oField.digits == 3) {
785
904
  return oFormat.aQuartersAbbrevSt[iQuarter];
786
905
  } else if (oField.digits == 4) {
@@ -813,11 +932,11 @@ DateFormat.prototype.oSymbols = {
813
932
  } else {
814
933
  for (var i = 0; i < aQuartersVariants.length; i++) {
815
934
  var aVariants = aQuartersVariants[i];
816
- var oFound = oParseHelper.findEntry(sValue, aVariants);
935
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
817
936
  if (oFound.index !== -1) {
818
937
  return {
819
938
  quarter: oFound.index,
820
- length: oFound.value.length
939
+ length: oFound.length
821
940
  };
822
941
  }
823
942
  }
@@ -832,7 +951,7 @@ DateFormat.prototype.oSymbols = {
832
951
  },
833
952
  'F': {
834
953
  name: 'dayOfWeekInMonth',
835
- format: function (oField, oDate, bUTC, oFormat) {
954
+ format: function (oField, oDate, oFormat) {
836
955
  return '';
837
956
  },
838
957
  parse: function () {
@@ -842,7 +961,7 @@ DateFormat.prototype.oSymbols = {
842
961
  'E': {
843
962
  name: 'dayNameInWeek',
844
963
  format: function (oField, oDate, bUTC, oFormat) {
845
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
964
+ var iDay = oDate.getUTCDay();
846
965
  if (oField.digits < 4) {
847
966
  return oFormat.aDaysAbbrev[iDay];
848
967
  } else if (oField.digits == 4) {
@@ -866,11 +985,11 @@ DateFormat.prototype.oSymbols = {
866
985
  ];
867
986
  for (var i = 0; i < aDaysVariants.length; i++) {
868
987
  var aVariants = aDaysVariants[i];
869
- var oFound = oParseHelper.findEntry(sValue, aVariants);
988
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
870
989
  if (oFound.index !== -1) {
871
990
  return {
872
991
  dayOfWeek: oFound.index,
873
- length: oFound.value.length
992
+ length: oFound.length
874
993
  };
875
994
  }
876
995
  }
@@ -879,7 +998,7 @@ DateFormat.prototype.oSymbols = {
879
998
  'c': {
880
999
  name: 'dayNameInWeekStandalone',
881
1000
  format: function (oField, oDate, bUTC, oFormat) {
882
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
1001
+ var iDay = oDate.getUTCDay();
883
1002
  if (oField.digits < 4) {
884
1003
  return oFormat.aDaysAbbrevSt[iDay];
885
1004
  } else if (oField.digits == 4) {
@@ -903,11 +1022,11 @@ DateFormat.prototype.oSymbols = {
903
1022
  ];
904
1023
  for (var i = 0; i < aDaysVariants.length; i++) {
905
1024
  var aVariants = aDaysVariants[i];
906
- var oFound = oParseHelper.findEntry(sValue, aVariants);
1025
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
907
1026
  if (oFound.index !== -1) {
908
1027
  return {
909
1028
  day: oFound.index,
910
- length: oFound.value.length
1029
+ length: oFound.length
911
1030
  };
912
1031
  }
913
1032
  }
@@ -916,7 +1035,7 @@ DateFormat.prototype.oSymbols = {
916
1035
  'u': {
917
1036
  name: 'dayNumberOfWeek',
918
1037
  format: function (oField, oDate, bUTC, oFormat) {
919
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
1038
+ var iDay = oDate.getUTCDay();
920
1039
  return oFormat._adaptDayOfWeek(iDay);
921
1040
  },
922
1041
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -930,38 +1049,96 @@ DateFormat.prototype.oSymbols = {
930
1049
  'a': {
931
1050
  name: 'amPmMarker',
932
1051
  format: function (oField, oDate, bUTC, oFormat) {
933
- var iDayPeriod = bUTC ? oDate.getUTCDayPeriod() : oDate.getDayPeriod();
934
- return oFormat.aDayPeriods[iDayPeriod];
1052
+ var iDayPeriod = oDate.getUTCDayPeriod();
1053
+ if (oField.digits <= 3) {
1054
+ return oFormat.aDayPeriodsAbbrev[iDayPeriod];
1055
+ } else if (oField.digits === 4) {
1056
+ return oFormat.aDayPeriodsWide[iDayPeriod];
1057
+ } else {
1058
+ return oFormat.aDayPeriodsNarrow[iDayPeriod];
1059
+ }
1060
+ },
1061
+ parse: function (sValue, oPart, oFormat, oConfig, sTimezone) {
1062
+ var rAMPM, bAMPMAlternativeCase, oEntry, i, aMatch, normalize, aVariants, aDayPeriodsVariants = [
1063
+ oFormat.aDayPeriodsWide,
1064
+ oFormat.aDayPeriodsAbbrev,
1065
+ oFormat.aDayPeriodsNarrow
1066
+ ];
1067
+ rAMPM = /[aApP](?:\.)?[\x20\xA0]?[mM](?:\.)?/;
1068
+ aMatch = sValue.match(rAMPM);
1069
+ bAMPMAlternativeCase = aMatch && aMatch.index === 0;
1070
+ function normalize(sValue) {
1071
+ return sValue.replace(/[\x20\xA0]/g, '').replace(/\./g, '');
1072
+ }
1073
+ if (bAMPMAlternativeCase) {
1074
+ sValue = normalize(sValue);
1075
+ }
1076
+ for (i = 0; i < aDayPeriodsVariants.length; i += 1) {
1077
+ aVariants = aDayPeriodsVariants[i];
1078
+ if (bAMPMAlternativeCase) {
1079
+ aVariants = aVariants.map(normalize);
1080
+ }
1081
+ oEntry = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
1082
+ if (oEntry.index !== -1) {
1083
+ return {
1084
+ pm: oEntry.index === 1,
1085
+ length: bAMPMAlternativeCase ? aMatch[0].length : oEntry.length
1086
+ };
1087
+ }
1088
+ }
1089
+ return { valid: false };
1090
+ }
1091
+ },
1092
+ 'B': {
1093
+ name: 'flexibleDayPeriod',
1094
+ format: function (oField, oDate, bUTC, oFormat) {
1095
+ var bContainsHour = oFormat.aFormatArray.some(function (oFormatElement) {
1096
+ return 'hHKk'.includes(oFormatElement.symbol);
1097
+ }), sFlexibleDayPeriod = oFormat.oLocaleData.getFlexibleDayPeriodOfTime(oDate.getUTCHours(), oDate.getUTCMinutes());
1098
+ if (bContainsHour) {
1099
+ if (oField.digits <= 3) {
1100
+ return oFormat.oFlexibleDayPeriodsAbbrev[sFlexibleDayPeriod];
1101
+ }
1102
+ if (oField.digits === 4) {
1103
+ return oFormat.oFlexibleDayPeriodsWide[sFlexibleDayPeriod];
1104
+ }
1105
+ return oFormat.oFlexibleDayPeriodsNarrow[sFlexibleDayPeriod];
1106
+ }
1107
+ if (oField.digits <= 3) {
1108
+ return oFormat.oFlexibleDayPeriodsAbbrevSt[sFlexibleDayPeriod];
1109
+ }
1110
+ if (oField.digits === 4) {
1111
+ return oFormat.oFlexibleDayPeriodsWideSt[sFlexibleDayPeriod];
1112
+ }
1113
+ return oFormat.oFlexibleDayPeriodsNarrowSt[sFlexibleDayPeriod];
935
1114
  },
936
1115
  parse: function (sValue, oPart, oFormat, oConfig) {
937
- var bPM;
938
- var iLength;
939
- var sAM = oFormat.aDayPeriods[0], sPM = oFormat.aDayPeriods[1];
940
- var rAMPM = /[aApP](?:\.)?[mM](?:\.)?/;
941
- var aMatch = sValue.match(rAMPM);
942
- var bVariant = aMatch && aMatch.index === 0;
943
- if (bVariant) {
944
- sValue = aMatch[0].replace(/\./g, '').toLowerCase() + sValue.substring(aMatch[0].length);
945
- sAM = sAM.replace(/\./g, '').toLowerCase();
946
- sPM = sPM.replace(/\./g, '').toLowerCase();
947
- }
948
- if (sValue.indexOf(sAM) === 0) {
949
- bPM = false;
950
- iLength = bVariant ? aMatch[0].length : sAM.length;
951
- } else if (sValue.indexOf(sPM) === 0) {
952
- bPM = true;
953
- iLength = bVariant ? aMatch[0].length : sPM.length;
1116
+ var i, oFound, oVariant, bContainsHour = oFormat.aFormatArray.some(function (oFormatElement) {
1117
+ return 'hHKk'.includes(oFormatElement.symbol);
1118
+ }), aFlexibleDayPeriodVariants = [
1119
+ oFormat.oFlexibleDayPeriodsWide,
1120
+ oFormat.oFlexibleDayPeriodsAbbrev,
1121
+ oFormat.oFlexibleDayPeriodsNarrow
1122
+ ];
1123
+ if (bContainsHour) {
1124
+ for (i = 0; i < aFlexibleDayPeriodVariants.length; i++) {
1125
+ oVariant = aFlexibleDayPeriodVariants[i];
1126
+ oFound = oParseHelper.findEntry(sValue, Object.values(oVariant), oFormat.oLocaleData.sCLDRLocaleId);
1127
+ if (oFound.index !== -1) {
1128
+ return {
1129
+ flexDayPeriod: Object.keys(oVariant)[oFound.index],
1130
+ length: oFound.length
1131
+ };
1132
+ }
1133
+ }
954
1134
  }
955
- return {
956
- pm: bPM,
957
- length: iLength
958
- };
1135
+ return { valid: false };
959
1136
  }
960
1137
  },
961
1138
  'H': {
962
1139
  name: 'hour0_23',
963
- format: function (oField, oDate, bUTC, oFormat) {
964
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1140
+ format: function (oField, oDate) {
1141
+ var iHours = oDate.getUTCHours();
965
1142
  return String(iHours).padStart(oField.digits, '0');
966
1143
  },
967
1144
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -981,8 +1158,8 @@ DateFormat.prototype.oSymbols = {
981
1158
  },
982
1159
  'k': {
983
1160
  name: 'hour1_24',
984
- format: function (oField, oDate, bUTC, oFormat) {
985
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1161
+ format: function (oField, oDate) {
1162
+ var iHours = oDate.getUTCHours();
986
1163
  var sHours = iHours === 0 ? '24' : String(iHours);
987
1164
  return sHours.padStart(oField.digits, '0');
988
1165
  },
@@ -1006,8 +1183,8 @@ DateFormat.prototype.oSymbols = {
1006
1183
  },
1007
1184
  'K': {
1008
1185
  name: 'hour0_11',
1009
- format: function (oField, oDate, bUTC, oFormat) {
1010
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1186
+ format: function (oField, oDate) {
1187
+ var iHours = oDate.getUTCHours();
1011
1188
  var sHours = String(iHours > 11 ? iHours - 12 : iHours);
1012
1189
  return sHours.padStart(oField.digits, '0');
1013
1190
  },
@@ -1028,8 +1205,8 @@ DateFormat.prototype.oSymbols = {
1028
1205
  },
1029
1206
  'h': {
1030
1207
  name: 'hour1_12',
1031
- format: function (oField, oDate, bUTC, oFormat) {
1032
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1208
+ format: function (oField, oDate) {
1209
+ var iHours = oDate.getUTCHours();
1033
1210
  var sHours;
1034
1211
  if (iHours > 12) {
1035
1212
  sHours = String(iHours - 12);
@@ -1062,8 +1239,8 @@ DateFormat.prototype.oSymbols = {
1062
1239
  },
1063
1240
  'm': {
1064
1241
  name: 'minute',
1065
- format: function (oField, oDate, bUTC, oFormat) {
1066
- var iMinutes = bUTC ? oDate.getUTCMinutes() : oDate.getMinutes();
1242
+ format: function (oField, oDate) {
1243
+ var iMinutes = oDate.getUTCMinutes();
1067
1244
  return String(iMinutes).padStart(oField.digits, '0');
1068
1245
  },
1069
1246
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -1083,8 +1260,8 @@ DateFormat.prototype.oSymbols = {
1083
1260
  },
1084
1261
  's': {
1085
1262
  name: 'second',
1086
- format: function (oField, oDate, bUTC, oFormat) {
1087
- var iSeconds = bUTC ? oDate.getUTCSeconds() : oDate.getSeconds();
1263
+ format: function (oField, oDate) {
1264
+ var iSeconds = oDate.getUTCSeconds();
1088
1265
  return String(iSeconds).padStart(oField.digits, '0');
1089
1266
  },
1090
1267
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -1104,8 +1281,8 @@ DateFormat.prototype.oSymbols = {
1104
1281
  },
1105
1282
  'S': {
1106
1283
  name: 'fractionalsecond',
1107
- format: function (oField, oDate, bUTC, oFormat) {
1108
- var iMilliseconds = bUTC ? oDate.getUTCMilliseconds() : oDate.getMilliseconds();
1284
+ format: function (oField, oDate) {
1285
+ var iMilliseconds = oDate.getUTCMilliseconds();
1109
1286
  var sMilliseconds = String(iMilliseconds);
1110
1287
  var sFractionalseconds = sMilliseconds.padStart(3, '0');
1111
1288
  sFractionalseconds = sFractionalseconds.substr(0, oField.digits);
@@ -1126,17 +1303,18 @@ DateFormat.prototype.oSymbols = {
1126
1303
  },
1127
1304
  'z': {
1128
1305
  name: 'timezoneGeneral',
1129
- format: function (oField, oDate, bUTC, oFormat) {
1130
- if (oField.digits > 3 && oDate.getTimezoneLong()) {
1306
+ format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1307
+ if (oField.digits > 3 && oDate.getTimezoneLong && oDate.getTimezoneLong()) {
1131
1308
  return oDate.getTimezoneLong();
1132
- } else if (oDate.getTimezoneShort()) {
1309
+ } else if (oDate.getTimezoneShort && oDate.getTimezoneShort()) {
1133
1310
  return oDate.getTimezoneShort();
1134
1311
  }
1312
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1135
1313
  var sTimeZone = 'GMT';
1136
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1137
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1314
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1315
+ var bPositiveOffset = iTimezoneOffset > 0;
1138
1316
  var iHourOffset = Math.floor(iTZOffset / 60);
1139
- var iMinuteOffset = iTZOffset % 60;
1317
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1140
1318
  if (!bUTC && iTZOffset != 0) {
1141
1319
  sTimeZone += bPositiveOffset ? '-' : '+';
1142
1320
  sTimeZone += String(iHourOffset).padStart(2, '0');
@@ -1155,13 +1333,13 @@ DateFormat.prototype.oSymbols = {
1155
1333
  iLength = 3;
1156
1334
  } else if (sValue.substring(0, 2) === 'UT') {
1157
1335
  iLength = 2;
1158
- } else if (sValue.charAt(0) == 'Z') {
1336
+ } else if (sValue.charAt(0) === 'Z') {
1159
1337
  iLength = 1;
1160
1338
  iTZDiff = 0;
1161
1339
  } else {
1162
- return { error: 'cannot be parsed correcly by sap.ui.core.format.DateFormat: The given timezone is not supported!' };
1340
+ return { error: 'cannot be parsed correctly by sap.ui.core.format.DateFormat: The given timezone is not supported!' };
1163
1341
  }
1164
- if (sValue.charAt(0) != 'Z') {
1342
+ if (sValue.charAt(0) !== 'Z') {
1165
1343
  var oParsedTZ = oParseHelper.parseTZ(sValue.substr(iLength), true);
1166
1344
  iLength += oParsedTZ.length;
1167
1345
  iTZDiff = oParsedTZ.tzDiff;
@@ -1174,13 +1352,14 @@ DateFormat.prototype.oSymbols = {
1174
1352
  },
1175
1353
  'Z': {
1176
1354
  name: 'timezoneRFC822',
1177
- format: function (oField, oDate, bUTC, oFormat) {
1178
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1179
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1355
+ format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1356
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1357
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1358
+ var bPositiveOffset = iTimezoneOffset > 0;
1180
1359
  var iHourOffset = Math.floor(iTZOffset / 60);
1181
- var iMinuteOffset = iTZOffset % 60;
1360
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1182
1361
  var sTimeZone = '';
1183
- if (!bUTC && iTZOffset != 0) {
1362
+ if (!bUTC) {
1184
1363
  sTimeZone += bPositiveOffset ? '-' : '+';
1185
1364
  sTimeZone += String(iHourOffset).padStart(2, '0');
1186
1365
  sTimeZone += String(iMinuteOffset).padStart(2, '0');
@@ -1193,37 +1372,83 @@ DateFormat.prototype.oSymbols = {
1193
1372
  },
1194
1373
  'X': {
1195
1374
  name: 'timezoneISO8601',
1196
- format: function (oField, oDate, bUTC, oFormat) {
1197
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1198
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1375
+ format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1376
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1377
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1378
+ var bPositiveOffset = iTimezoneOffset > 0;
1199
1379
  var iHourOffset = Math.floor(iTZOffset / 60);
1200
- var iMinuteOffset = iTZOffset % 60;
1380
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1201
1381
  var sTimeZone = '';
1202
1382
  if (!bUTC && iTZOffset != 0) {
1203
1383
  sTimeZone += bPositiveOffset ? '-' : '+';
1204
1384
  sTimeZone += String(iHourOffset).padStart(2, '0');
1205
- sTimeZone += ':';
1206
- sTimeZone += String(iMinuteOffset).padStart(2, '0');
1385
+ if (oField.digits > 1 || iMinuteOffset > 0) {
1386
+ if (oField.digits === 3 || oField.digits === 5) {
1387
+ sTimeZone += ':';
1388
+ }
1389
+ sTimeZone += String(iMinuteOffset).padStart(2, '0');
1390
+ }
1207
1391
  } else {
1208
1392
  sTimeZone += 'Z';
1209
1393
  }
1210
1394
  return sTimeZone;
1211
1395
  },
1212
1396
  parse: function (sValue, oPart, oFormat, oConfig) {
1213
- if (sValue.charAt(0) == 'Z') {
1397
+ if (sValue.charAt(0) === 'Z') {
1214
1398
  return {
1215
1399
  length: 1,
1216
1400
  tzDiff: 0
1217
1401
  };
1218
1402
  } else {
1219
- return oParseHelper.parseTZ(sValue, true);
1403
+ return oParseHelper.parseTZ(sValue, oPart.digits === 3 || oPart.digits === 5);
1404
+ }
1405
+ }
1406
+ },
1407
+ 'V': {
1408
+ name: 'timezoneID',
1409
+ format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1410
+ if (!bUTC && oField.digits === 2) {
1411
+ return oFormat.oLocaleData.getTimezoneTranslations()[sTimezone] || sTimezone;
1412
+ }
1413
+ return '';
1414
+ },
1415
+ parse: function (sValue, oPart, oFormat, oConfig, sTimezone) {
1416
+ var oTimezoneParsed = {
1417
+ timezone: '',
1418
+ length: 0
1419
+ };
1420
+ if (oPart.digits === 2) {
1421
+ var mTimezoneTranslations = oFormat.oLocaleData.getTimezoneTranslations();
1422
+ if (sValue === mTimezoneTranslations[sTimezone]) {
1423
+ return {
1424
+ timezone: sTimezone,
1425
+ length: sValue.length
1426
+ };
1427
+ }
1428
+ var aTimezoneTranslations = Object.values(mTimezoneTranslations);
1429
+ var oTimezoneResult = oParseHelper.findEntry(sValue, aTimezoneTranslations, oFormat.oLocaleData.sCLDRLocaleId);
1430
+ if (oTimezoneResult.index !== -1) {
1431
+ return {
1432
+ timezone: Object.keys(mTimezoneTranslations)[oTimezoneResult.index],
1433
+ length: oTimezoneResult.length
1434
+ };
1435
+ }
1436
+ var sCurrentValue = '';
1437
+ for (var i = 0; i < sValue.length; i++) {
1438
+ sCurrentValue += sValue[i];
1439
+ if (TimezoneUtil.isValidTimezone(sCurrentValue)) {
1440
+ oTimezoneParsed.timezone = sCurrentValue;
1441
+ oTimezoneParsed.length = sCurrentValue.length;
1442
+ }
1443
+ }
1220
1444
  }
1445
+ return oTimezoneParsed;
1221
1446
  }
1222
1447
  }
1223
1448
  };
1224
- DateFormat.prototype._format = function (oJSDate, bUTC) {
1449
+ DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1225
1450
  if (this.oFormatOptions.relative) {
1226
- var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange);
1451
+ var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange, sTimezone);
1227
1452
  if (sRes) {
1228
1453
  return sRes;
1229
1454
  }
@@ -1234,10 +1459,10 @@ DateFormat.prototype._format = function (oJSDate, bUTC) {
1234
1459
  for (var i = 0; i < this.aFormatArray.length; i++) {
1235
1460
  oPart = this.aFormatArray[i];
1236
1461
  sSymbol = oPart.symbol || '';
1237
- aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this));
1462
+ aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this, sTimezone));
1238
1463
  }
1239
1464
  sResult = aBuffer.join('');
1240
- if (Core.getConfiguration().getOriginInfo()) {
1465
+ if (Configuration.getOriginInfo()) {
1241
1466
  sResult = new String(sResult);
1242
1467
  sResult.originInfo = {
1243
1468
  source: 'Common Locale Data Repository',
@@ -1249,10 +1474,21 @@ DateFormat.prototype._format = function (oJSDate, bUTC) {
1249
1474
  return sResult;
1250
1475
  };
1251
1476
  DateFormat.prototype.format = function (vJSDate, bUTC) {
1477
+ var sTimezone;
1478
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1479
+ sTimezone = bUTC;
1480
+ bUTC = false;
1481
+ checkTimezoneParameterType(sTimezone);
1482
+ if (sTimezone && !TimezoneUtil.isValidTimezone(sTimezone)) {
1483
+ Log.error('The given timezone isn\'t valid.');
1484
+ return '';
1485
+ }
1486
+ }
1252
1487
  var sCalendarType = this.oFormatOptions.calendarType, sResult;
1253
1488
  if (bUTC === undefined) {
1254
1489
  bUTC = this.oFormatOptions.UTC;
1255
1490
  }
1491
+ sTimezone = sTimezone || Configuration.getTimezone();
1256
1492
  if (Array.isArray(vJSDate)) {
1257
1493
  if (!this.oFormatOptions.interval) {
1258
1494
  Log.error('Non-interval DateFormat can\'t format more than one date instance.');
@@ -1262,27 +1498,30 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1262
1498
  Log.error('Interval DateFormat can only format with 2 date instances but ' + vJSDate.length + ' is given.');
1263
1499
  return '';
1264
1500
  }
1501
+ vJSDate = vJSDate.map(function (oJSDate) {
1502
+ return convertToTimezone(oJSDate, sTimezone, bUTC);
1503
+ });
1265
1504
  if (this.oFormatOptions.singleIntervalValue) {
1266
1505
  if (vJSDate[0] === null) {
1267
1506
  Log.error('First date instance which is passed to the interval DateFormat shouldn\'t be null.');
1268
1507
  return '';
1269
1508
  }
1270
1509
  if (vJSDate[1] === null) {
1271
- sResult = this._format(vJSDate[0], bUTC);
1510
+ sResult = this._format(vJSDate[0], bUTC, sTimezone);
1272
1511
  }
1273
1512
  }
1274
1513
  if (sResult === undefined) {
1275
- var bValid = vJSDate.every(function (oJSDate) {
1276
- return oJSDate && !isNaN(oJSDate.getTime());
1277
- });
1278
- if (!bValid) {
1514
+ if (!vJSDate.every(isValidDateObject)) {
1279
1515
  Log.error('At least one date instance which is passed to the interval DateFormat isn\'t valid.');
1280
1516
  return '';
1281
1517
  }
1282
1518
  sResult = this._formatInterval(vJSDate, bUTC);
1283
1519
  }
1284
1520
  } else {
1285
- if (!vJSDate || isNaN(vJSDate.getTime())) {
1521
+ if (!isValidDateObject(vJSDate)) {
1522
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE && this.oFormatOptions.pattern.includes('VV')) {
1523
+ return this.oLocaleData.getTimezoneTranslations()[sTimezone] || sTimezone;
1524
+ }
1286
1525
  Log.error('The given date instance isn\'t valid.');
1287
1526
  return '';
1288
1527
  }
@@ -1290,7 +1529,8 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1290
1529
  Log.error('Interval DateFormat expects an array with two dates for the first argument but only one date is given.');
1291
1530
  return '';
1292
1531
  }
1293
- sResult = this._format(vJSDate, bUTC);
1532
+ vJSDate = convertToTimezone(vJSDate, sTimezone, bUTC);
1533
+ sResult = this._format(vJSDate, bUTC, sTimezone);
1294
1534
  }
1295
1535
  if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1296
1536
  sResult = sResult.replace(/(^|[^\d])1年/g, '$1元年');
@@ -1310,7 +1550,7 @@ DateFormat.prototype._formatInterval = function (aJSDates, bUTC) {
1310
1550
  var oDiffField = this._getGreatestDiffField([
1311
1551
  oFromDate,
1312
1552
  oToDate
1313
- ], bUTC);
1553
+ ]);
1314
1554
  if (!oDiffField) {
1315
1555
  return this._format(aJSDates[0], bUTC);
1316
1556
  }
@@ -1343,10 +1583,10 @@ var mFieldToGroup = {
1343
1583
  Minutes: 'Minute',
1344
1584
  Seconds: 'Second'
1345
1585
  };
1346
- DateFormat.prototype._getGreatestDiffField = function (aDates, bUTC) {
1586
+ DateFormat.prototype._getGreatestDiffField = function (aDates) {
1347
1587
  var bDiffFound = false, mDiff = {};
1348
1588
  this.aIntervalCompareFields.forEach(function (sField) {
1349
- var sGetterPrefix = 'get' + (bUTC ? 'UTC' : ''), sMethodName = sGetterPrefix + sField, sFieldGroup = mFieldToGroup[sField], vFromValue = aDates[0][sMethodName].apply(aDates[0]), vToValue = aDates[1][sMethodName].apply(aDates[1]);
1589
+ var sGetterPrefix = 'getUTC', sMethodName = sGetterPrefix + sField, sFieldGroup = mFieldToGroup[sField], vFromValue = aDates[0][sMethodName].apply(aDates[0]), vToValue = aDates[1][sMethodName].apply(aDates[1]);
1350
1590
  if (!deepEqual(vFromValue, vToValue)) {
1351
1591
  bDiffFound = true;
1352
1592
  mDiff[sFieldGroup] = true;
@@ -1357,9 +1597,12 @@ DateFormat.prototype._getGreatestDiffField = function (aDates, bUTC) {
1357
1597
  }
1358
1598
  return null;
1359
1599
  };
1360
- DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1361
- var iIndex = 0, oPart, sSubValue, oResult;
1362
- var oDateValue = { valid: true };
1600
+ 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
+ };
1363
1606
  var oParseConf = {
1364
1607
  formatArray: aFormatArray,
1365
1608
  dateValue: oDateValue,
@@ -1369,7 +1612,10 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1369
1612
  sSubValue = sValue.substr(iIndex);
1370
1613
  oPart = aFormatArray[i];
1371
1614
  oParseConf.index = i;
1372
- oResult = this.oSymbols[oPart.symbol || ''].parse(sSubValue, oPart, this, oParseConf) || {};
1615
+ oResult = this.oSymbols[oPart.symbol || ''].parse(sSubValue, oPart, this, oParseConf, sTimezone) || {};
1616
+ if (oResult.tzDiff !== undefined || oResult.timezone) {
1617
+ oResult.lastTimezonePatternSymbol = oPart.symbol;
1618
+ }
1373
1619
  oDateValue = extend(oDateValue, oResult);
1374
1620
  if (oResult.valid === false) {
1375
1621
  break;
@@ -1377,7 +1623,12 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1377
1623
  iIndex += oResult.length || 0;
1378
1624
  }
1379
1625
  oDateValue.index = iIndex;
1380
- if (oDateValue.pm) {
1626
+ bPM = oDateValue.pm;
1627
+ if (oDateValue.flexDayPeriod && oDateValue.hour * 60 + (oDateValue.minute || 0) < 720) {
1628
+ sFlexibleDayPeriod = this.oLocaleData.getFlexibleDayPeriodOfTime(oDateValue.hour + 12, oDateValue.minute || 0);
1629
+ bPM = oDateValue.flexDayPeriod === sFlexibleDayPeriod;
1630
+ }
1631
+ if (bPM) {
1381
1632
  oDateValue.hour += 12;
1382
1633
  }
1383
1634
  if (oDateValue.dayNumberOfWeek === undefined && oDateValue.dayOfWeek !== undefined) {
@@ -1389,7 +1640,7 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1389
1640
  }
1390
1641
  return oDateValue;
1391
1642
  };
1392
- DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bStrict) {
1643
+ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bStrict, sTimezone) {
1393
1644
  var aDateValues, iRepeat, oDateValue;
1394
1645
  this.intervalPatterns.some(function (sPattern) {
1395
1646
  var aFormatArray = this.parseCldrDatePattern(sPattern);
@@ -1401,7 +1652,7 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1401
1652
  }
1402
1653
  }
1403
1654
  if (iRepeat === undefined) {
1404
- oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict);
1655
+ oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict, sTimezone);
1405
1656
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1406
1657
  oDateValue.valid = false;
1407
1658
  }
@@ -1415,13 +1666,13 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1415
1666
  return true;
1416
1667
  } else {
1417
1668
  aDateValues = [];
1418
- oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict);
1669
+ oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict, sTimezone);
1419
1670
  if (oDateValue.valid === false) {
1420
1671
  return;
1421
1672
  }
1422
1673
  aDateValues.push(oDateValue);
1423
1674
  var iLength = oDateValue.index;
1424
- oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict);
1675
+ oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict, sTimezone);
1425
1676
  if (oDateValue.index === 0 || oDateValue.index + iLength < sValue.length) {
1426
1677
  oDateValue.valid = false;
1427
1678
  }
@@ -1434,65 +1685,62 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1434
1685
  }.bind(this));
1435
1686
  return aDateValues;
1436
1687
  };
1437
- var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict) {
1688
+ function getCalendarWeekParameter(oFormatOptions) {
1689
+ if (oFormatOptions.calendarWeekNumbering) {
1690
+ return oFormatOptions.calendarWeekNumbering;
1691
+ } else if (oFormatOptions.firstDayOfWeek !== undefined && oFormatOptions.minimalDaysInFirstWeek !== undefined) {
1692
+ return {
1693
+ firstDayOfWeek: oFormatOptions.firstDayOfWeek,
1694
+ minimalDaysInFirstWeek: oFormatOptions.minimalDaysInFirstWeek
1695
+ };
1696
+ }
1697
+ return undefined;
1698
+ }
1699
+ var convertToTimezone = function (oJSDate, sTimezone, bUTC) {
1700
+ if (!bUTC && isValidDateObject(oJSDate)) {
1701
+ return TimezoneUtil.convertToTimezone(oJSDate, sTimezone);
1702
+ }
1703
+ return oJSDate;
1704
+ };
1705
+ var fnCreateDate = function (oDateValue, sCalendarType, bUTC, bStrict, sTimezone, oFormatOptions, oLocale) {
1706
+ if (!oDateValue.valid) {
1707
+ return null;
1708
+ }
1438
1709
  var oDate, iYear = typeof oDateValue.year === 'number' ? oDateValue.year : 1970;
1439
- if (oDateValue.valid) {
1440
- if (bUTC || oDateValue.tzDiff !== undefined) {
1441
- oDate = UniversalDate.getInstance(new Date(0), sCalendarType);
1442
- oDate.setUTCEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1443
- oDate.setUTCFullYear(iYear);
1444
- oDate.setUTCMonth(oDateValue.month || 0);
1445
- oDate.setUTCDate(oDateValue.day || 1);
1446
- oDate.setUTCHours(oDateValue.hour || 0);
1447
- oDate.setUTCMinutes(oDateValue.minute || 0);
1448
- oDate.setUTCSeconds(oDateValue.second || 0);
1449
- oDate.setUTCMilliseconds(oDateValue.millisecond || 0);
1450
- if (bStrict && (oDateValue.day || 1) !== oDate.getUTCDate()) {
1451
- oDateValue.valid = false;
1452
- oDate = undefined;
1453
- } else {
1454
- if (oDateValue.tzDiff) {
1455
- oDate.setUTCMinutes((oDateValue.minute || 0) + oDateValue.tzDiff);
1456
- }
1457
- if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1458
- oDate.setUTCWeek({
1459
- year: oDateValue.weekYear || oDateValue.year,
1460
- week: oDateValue.week
1461
- });
1462
- if (oDateValue.dayNumberOfWeek !== undefined) {
1463
- oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1464
- }
1465
- }
1466
- }
1467
- } else {
1468
- oDate = UniversalDate.getInstance(new Date(1970, 0, 1, 0, 0, 0), sCalendarType);
1469
- oDate.setEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1470
- oDate.setFullYear(iYear);
1471
- oDate.setMonth(oDateValue.month || 0);
1472
- oDate.setDate(oDateValue.day || 1);
1473
- oDate.setHours(oDateValue.hour || 0);
1474
- oDate.setMinutes(oDateValue.minute || 0);
1475
- oDate.setSeconds(oDateValue.second || 0);
1476
- oDate.setMilliseconds(oDateValue.millisecond || 0);
1477
- if (bStrict && (oDateValue.day || 1) !== oDate.getDate()) {
1478
- oDateValue.valid = false;
1479
- oDate = undefined;
1480
- } else if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1481
- oDate.setWeek({
1482
- year: oDateValue.weekYear || oDateValue.year,
1483
- week: oDateValue.week
1484
- });
1485
- if (oDateValue.dayNumberOfWeek !== undefined) {
1486
- oDate.setDate(oDate.getDate() + oDateValue.dayNumberOfWeek - 1);
1487
- }
1488
- }
1710
+ oDate = UniversalDate.getInstance(new Date(0), sCalendarType);
1711
+ oDate.setUTCEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1712
+ oDate.setUTCFullYear(iYear);
1713
+ oDate.setUTCMonth(oDateValue.month || 0);
1714
+ oDate.setUTCDate(oDateValue.day || 1);
1715
+ oDate.setUTCHours(oDateValue.hour || 0);
1716
+ oDate.setUTCMinutes(oDateValue.minute || 0);
1717
+ oDate.setUTCSeconds(oDateValue.second || 0);
1718
+ oDate.setUTCMilliseconds(oDateValue.millisecond || 0);
1719
+ if (bStrict && (oDateValue.day || 1) !== oDate.getUTCDate()) {
1720
+ return null;
1721
+ }
1722
+ if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1723
+ oDate.setUTCWeek({
1724
+ year: oDateValue.weekYear || oDateValue.year,
1725
+ week: oDateValue.week
1726
+ }, oLocale, getCalendarWeekParameter(oFormatOptions));
1727
+ if (oDateValue.dayNumberOfWeek !== undefined) {
1728
+ oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1729
+ }
1730
+ }
1731
+ oDate = oDate.getJSDate();
1732
+ if (!bUTC && (oDateValue.lastTimezonePatternSymbol === 'V' && oDateValue.timezone || oDateValue.tzDiff === undefined)) {
1733
+ if (oDateValue.timezone) {
1734
+ sTimezone = oDateValue.timezone;
1489
1735
  }
1490
- if (oDateValue.valid) {
1491
- oDate = oDate.getJSDate();
1492
- return oDate;
1736
+ if (sTimezone) {
1737
+ oDateValue.tzDiff = TimezoneUtil.calculateOffset(oDate, sTimezone);
1493
1738
  }
1494
1739
  }
1495
- return null;
1740
+ if (oDateValue.tzDiff) {
1741
+ oDate.setUTCSeconds(oDate.getUTCSeconds() + oDateValue.tzDiff);
1742
+ }
1743
+ return oDate;
1496
1744
  };
1497
1745
  function mergeWithoutOverwrite(object1, object2) {
1498
1746
  if (object1 === object2) {
@@ -1515,13 +1763,33 @@ function isValidDateRange(oStartDate, oEndDate) {
1515
1763
  }
1516
1764
  return true;
1517
1765
  }
1766
+ function isValidDateObject(oDate) {
1767
+ return oDate && typeof oDate.getTime === 'function' && !isNaN(oDate.getTime());
1768
+ }
1518
1769
  DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1770
+ var bShowDate = this.oFormatOptions.showDate === undefined || this.oFormatOptions.showDate;
1771
+ var bShowTime = this.oFormatOptions.showTime === undefined || this.oFormatOptions.showTime;
1772
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE && (bShowDate && !bShowTime || !bShowDate && bShowTime)) {
1773
+ throw new TypeError('The input can only be parsed back to date if both date and time are supplied.');
1774
+ }
1775
+ var sTimezone;
1776
+ if (bUTC === undefined && this.type !== mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1777
+ bUTC = this.oFormatOptions.UTC;
1778
+ }
1779
+ var bUTCInputParameter = bUTC;
1780
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1781
+ sTimezone = bUTC;
1782
+ bUTC = false;
1783
+ checkTimezoneParameterType(sTimezone);
1784
+ if (sTimezone && !TimezoneUtil.isValidTimezone(sTimezone)) {
1785
+ Log.error('The given timezone isn\'t valid.');
1786
+ return null;
1787
+ }
1788
+ }
1519
1789
  sValue = sValue == null ? '' : String(sValue).trim();
1520
1790
  var oDateValue;
1521
1791
  var sCalendarType = this.oFormatOptions.calendarType;
1522
- if (bUTC === undefined) {
1523
- bUTC = this.oFormatOptions.UTC;
1524
- }
1792
+ sTimezone = sTimezone || Configuration.getTimezone();
1525
1793
  if (bStrict === undefined) {
1526
1794
  bStrict = this.oFormatOptions.strictParsing;
1527
1795
  }
@@ -1533,22 +1801,40 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1533
1801
  if (oJSDate) {
1534
1802
  return oJSDate;
1535
1803
  }
1536
- oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict);
1804
+ oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict, sTimezone);
1537
1805
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1538
1806
  oDateValue.valid = false;
1539
1807
  }
1540
- oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict);
1808
+ oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1541
1809
  if (oJSDate) {
1810
+ if (this.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1811
+ var bShowTimezone = this.oFormatOptions.showTimezone === undefined || this.oFormatOptions.showTimezone;
1812
+ if (!bShowTimezone && bShowDate && bShowTime) {
1813
+ return [
1814
+ oJSDate,
1815
+ undefined
1816
+ ];
1817
+ } else if (bShowTimezone && !bShowDate && !bShowTime) {
1818
+ return [
1819
+ undefined,
1820
+ oDateValue.timezone
1821
+ ];
1822
+ }
1823
+ return [
1824
+ oJSDate,
1825
+ oDateValue.timezone || undefined
1826
+ ];
1827
+ }
1542
1828
  return oJSDate;
1543
1829
  }
1544
1830
  } else {
1545
- var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict);
1831
+ var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict, sTimezone);
1546
1832
  var oJSDate1, oJSDate2;
1547
1833
  if (aDateValues && aDateValues.length == 2) {
1548
1834
  var oDateValue1 = mergeWithoutOverwrite(aDateValues[0], aDateValues[1]);
1549
1835
  var oDateValue2 = mergeWithoutOverwrite(aDateValues[1], aDateValues[0]);
1550
- oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict);
1551
- oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict);
1836
+ oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1837
+ oJSDate2 = fnCreateDate(oDateValue2, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1552
1838
  if (oJSDate1 && oJSDate2) {
1553
1839
  if (this.oFormatOptions.singleIntervalValue && oJSDate1.getTime() === oJSDate2.getTime()) {
1554
1840
  return [
@@ -1574,8 +1860,11 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1574
1860
  if (!this.bIsFallback) {
1575
1861
  var vDate;
1576
1862
  this.aFallbackFormats.every(function (oFallbackFormat) {
1577
- vDate = oFallbackFormat.parse(sValue, bUTC, bStrict);
1863
+ vDate = oFallbackFormat.parse(sValue, bUTCInputParameter, bStrict);
1578
1864
  if (Array.isArray(vDate)) {
1865
+ if (oFallbackFormat.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1866
+ return false;
1867
+ }
1579
1868
  return !(vDate[0] && vDate[1]);
1580
1869
  } else {
1581
1870
  return !vDate;
@@ -1724,23 +2013,20 @@ DateFormat.prototype.parseRelative = function (sValue, bUTC) {
1724
2013
  }
1725
2014
  }
1726
2015
  };
1727
- DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange) {
1728
- var oToday = new Date(), oDateUTC, sScale = this.oFormatOptions.relativeScale || 'day', iDiff, sPattern, iDiffSeconds;
2016
+ DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange, sTimezone) {
2017
+ var oToday = convertToTimezone(new Date(), sTimezone), oDateUTC, sScale = this.oFormatOptions.relativeScale || 'day', iDiff, sPattern, iDiffSeconds;
1729
2018
  iDiffSeconds = (oJSDate.getTime() - oToday.getTime()) / 1000;
1730
2019
  if (this.oFormatOptions.relativeScale == 'auto') {
1731
2020
  sScale = this._getScale(iDiffSeconds, this.aRelativeScales);
2021
+ sScale = fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds);
1732
2022
  }
1733
2023
  if (!aRange) {
1734
2024
  aRange = this._mRanges[sScale];
1735
2025
  }
1736
2026
  if (sScale == 'year' || sScale == 'month' || sScale == 'day') {
1737
- oToday = new Date(Date.UTC(oToday.getFullYear(), oToday.getMonth(), oToday.getDate()));
2027
+ oToday = new Date(Date.UTC(oToday.getUTCFullYear(), oToday.getUTCMonth(), oToday.getUTCDate()));
1738
2028
  oDateUTC = new Date(0);
1739
- if (bUTC) {
1740
- oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
1741
- } else {
1742
- oDateUTC.setUTCFullYear(oJSDate.getFullYear(), oJSDate.getMonth(), oJSDate.getDate());
1743
- }
2029
+ oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
1744
2030
  oJSDate = oDateUTC;
1745
2031
  }
1746
2032
  iDiff = this._getDifference(sScale, [
@@ -1808,6 +2094,21 @@ DateFormat.prototype._getScale = function (iDiffSeconds, aScales) {
1808
2094
  }
1809
2095
  return sScale;
1810
2096
  };
2097
+ function fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds) {
2098
+ var iMonthDiff = Math.abs(oJSDate.getUTCMonth() - oToday.getUTCMonth());
2099
+ if (sScale === 'week' && iMonthDiff === 2) {
2100
+ return 'month';
2101
+ } else if (sScale === 'week' && iMonthDiff === 1) {
2102
+ if (oJSDate.getUTCDate() === oToday.getUTCDate() || iDiffSeconds < 0 && oJSDate.getUTCDate() < oToday.getUTCDate() || iDiffSeconds > 0 && oJSDate.getUTCDate() > oToday.getUTCDate()) {
2103
+ return 'month';
2104
+ }
2105
+ } else if (sScale === 'month' && iMonthDiff === 1) {
2106
+ if (iDiffSeconds > 0 && oJSDate.getUTCDate() < oToday.getUTCDate() || iDiffSeconds < 0 && oJSDate.getUTCDate() > oToday.getUTCDate()) {
2107
+ return 'week';
2108
+ }
2109
+ }
2110
+ return sScale;
2111
+ }
1811
2112
  function cutDateFields(oDate, iStartIndex) {
1812
2113
  var aFields = [
1813
2114
  'FullYear',
@@ -1818,48 +2119,55 @@ function cutDateFields(oDate, iStartIndex) {
1818
2119
  'Seconds',
1819
2120
  'Milliseconds'
1820
2121
  ], sMethodName;
2122
+ var oDateCopy = new Date(oDate.getTime());
1821
2123
  for (var i = iStartIndex; i < aFields.length; i++) {
1822
- sMethodName = 'set' + aFields[iStartIndex];
1823
- oDate[sMethodName].apply(oDate, [0]);
2124
+ sMethodName = 'setUTC' + aFields[iStartIndex];
2125
+ oDateCopy[sMethodName].apply(oDateCopy, [0]);
1824
2126
  }
2127
+ return oDateCopy;
1825
2128
  }
1826
2129
  var mRelativeDiffs = {
1827
2130
  year: function (oFromDate, oToDate) {
1828
- return oToDate.getFullYear() - oFromDate.getFullYear();
2131
+ return oToDate.getUTCFullYear() - oFromDate.getUTCFullYear();
1829
2132
  },
1830
2133
  month: function (oFromDate, oToDate) {
1831
- return oToDate.getMonth() - oFromDate.getMonth() + this.year(oFromDate, oToDate) * 12;
2134
+ return oToDate.getUTCMonth() - oFromDate.getUTCMonth() + this.year(oFromDate, oToDate) * 12;
1832
2135
  },
1833
2136
  week: function (oFromDate, oToDate, oFormat) {
1834
- var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getDay());
1835
- var iToDay = oFormat._adaptDayOfWeek(oToDate.getDay());
1836
- cutDateFields(oFromDate, 3);
1837
- cutDateFields(oToDate, 3);
2137
+ var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getUTCDay());
2138
+ var iToDay = oFormat._adaptDayOfWeek(oToDate.getUTCDay());
2139
+ oFromDate = cutDateFields(oFromDate, 3);
2140
+ oToDate = cutDateFields(oToDate, 3);
1838
2141
  return (oToDate.getTime() - oFromDate.getTime() - (iToDay - iFromDay) * oFormat._mScales.day * 1000) / (oFormat._mScales.week * 1000);
1839
2142
  },
1840
2143
  day: function (oFromDate, oToDate, oFormat) {
1841
- cutDateFields(oFromDate, 3);
1842
- cutDateFields(oToDate, 3);
2144
+ oFromDate = cutDateFields(oFromDate, 3);
2145
+ oToDate = cutDateFields(oToDate, 3);
1843
2146
  return (oToDate.getTime() - oFromDate.getTime()) / (oFormat._mScales.day * 1000);
1844
2147
  },
1845
2148
  hour: function (oFromDate, oToDate, oFormat) {
1846
- cutDateFields(oFromDate, 4);
1847
- cutDateFields(oToDate, 4);
2149
+ oFromDate = cutDateFields(oFromDate, 4);
2150
+ oToDate = cutDateFields(oToDate, 4);
1848
2151
  return (oToDate.getTime() - oFromDate.getTime()) / (oFormat._mScales.hour * 1000);
1849
2152
  },
1850
2153
  minute: function (oFromDate, oToDate, oFormat) {
1851
- cutDateFields(oFromDate, 5);
1852
- cutDateFields(oToDate, 5);
2154
+ oFromDate = cutDateFields(oFromDate, 5);
2155
+ oToDate = cutDateFields(oToDate, 5);
1853
2156
  return (oToDate.getTime() - oFromDate.getTime()) / (oFormat._mScales.minute * 1000);
1854
2157
  },
1855
2158
  second: function (oFromDate, oToDate, oFormat) {
1856
- cutDateFields(oFromDate, 6);
1857
- cutDateFields(oToDate, 6);
2159
+ oFromDate = cutDateFields(oFromDate, 6);
2160
+ oToDate = cutDateFields(oToDate, 6);
1858
2161
  return (oToDate.getTime() - oFromDate.getTime()) / (oFormat._mScales.second * 1000);
1859
2162
  }
1860
2163
  };
1861
2164
  DateFormat.prototype._adaptDayOfWeek = function (iDayOfWeek) {
1862
- var iFirstDayOfWeek = LocaleData.getInstance(Core.getConfiguration().getFormatSettings().getFormatLocale()).getFirstDayOfWeek();
2165
+ var vCalendarWeekParameter = getCalendarWeekParameter(this.oFormatOptions), iFirstDayOfWeek;
2166
+ if (typeof vCalendarWeekParameter === 'object') {
2167
+ iFirstDayOfWeek = vCalendarWeekParameter.firstDayOfWeek;
2168
+ } else {
2169
+ iFirstDayOfWeek = CalendarUtils.getWeekConfigurationValues(vCalendarWeekParameter, this.oLocale).firstDayOfWeek;
2170
+ }
1863
2171
  var iDayNumberOfWeek = iDayOfWeek - (iFirstDayOfWeek - 1);
1864
2172
  if (iDayNumberOfWeek <= 0) {
1865
2173
  iDayNumberOfWeek += 7;