@ui5/webcomponents-localization 0.0.0-2c7615fe9 → 0.0.0-2f7664755

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 (202) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/README.md +36 -6
  3. package/dist/Assets-static.d.ts +1 -0
  4. package/dist/Assets-static.js +1 -0
  5. package/dist/Assets-static.js.map +1 -0
  6. package/dist/Assets.d.ts +1 -0
  7. package/dist/Assets.js +1 -0
  8. package/dist/Assets.js.map +1 -0
  9. package/dist/DateFormat.d.ts +6 -0
  10. package/dist/DateFormat.js +6 -2
  11. package/dist/DateFormat.js.map +1 -0
  12. package/dist/LocaleData.d.ts +6 -0
  13. package/dist/LocaleData.js +6 -2
  14. package/dist/LocaleData.js.map +1 -0
  15. package/dist/dates/CalendarDate.d.ts +41 -0
  16. package/dist/dates/CalendarDate.js +170 -201
  17. package/dist/dates/CalendarDate.js.map +1 -0
  18. package/dist/dates/ExtremeDates.d.ts +5 -0
  19. package/dist/dates/ExtremeDates.js +25 -35
  20. package/dist/dates/ExtremeDates.js.map +1 -0
  21. package/dist/dates/UniversalDate.d.ts +46 -0
  22. package/dist/dates/UniversalDate.js +5 -0
  23. package/dist/dates/UniversalDate.js.map +1 -0
  24. package/dist/dates/calculateWeekNumber.d.ts +4 -0
  25. package/dist/dates/calculateWeekNumber.js +42 -48
  26. package/dist/dates/calculateWeekNumber.js.map +1 -0
  27. package/dist/dates/convertMonthNumbersToMonthNames.d.ts +16 -0
  28. package/dist/dates/convertMonthNumbersToMonthNames.js +30 -0
  29. package/dist/dates/convertMonthNumbersToMonthNames.js.map +1 -0
  30. package/dist/dates/getDaysInMonth.d.ts +3 -0
  31. package/dist/dates/getDaysInMonth.js +10 -0
  32. package/dist/dates/getDaysInMonth.js.map +1 -0
  33. package/dist/dates/getRoundedTimestamp.d.ts +7 -0
  34. package/dist/dates/getRoundedTimestamp.js +9 -9
  35. package/dist/dates/getRoundedTimestamp.js.map +1 -0
  36. package/dist/dates/getTodayUTCTimestamp.d.ts +7 -0
  37. package/dist/dates/getTodayUTCTimestamp.js +2 -3
  38. package/dist/dates/getTodayUTCTimestamp.js.map +1 -0
  39. package/dist/dates/modifyDateBy.d.ts +13 -0
  40. package/dist/dates/modifyDateBy.js +27 -29
  41. package/dist/dates/modifyDateBy.js.map +1 -0
  42. package/dist/dates/transformDateToSecondaryType.d.ts +7 -0
  43. package/dist/dates/transformDateToSecondaryType.js +17 -0
  44. package/dist/dates/transformDateToSecondaryType.js.map +1 -0
  45. package/{src/features/calendar/Buddhist.js → dist/features/calendar/Buddhist.d.ts} +0 -0
  46. package/dist/features/calendar/Buddhist.js +1 -0
  47. package/dist/features/calendar/Buddhist.js.map +1 -0
  48. package/{src/features/calendar/Gregorian.js → dist/features/calendar/Gregorian.d.ts} +0 -0
  49. package/dist/features/calendar/Gregorian.js +1 -0
  50. package/dist/features/calendar/Gregorian.js.map +1 -0
  51. package/{src/features/calendar/Islamic.js → dist/features/calendar/Islamic.d.ts} +0 -0
  52. package/dist/features/calendar/Islamic.js +1 -0
  53. package/dist/features/calendar/Islamic.js.map +1 -0
  54. package/{src/features/calendar/Japanese.js → dist/features/calendar/Japanese.d.ts} +0 -0
  55. package/dist/features/calendar/Japanese.js +1 -0
  56. package/dist/features/calendar/Japanese.js.map +1 -0
  57. package/{src/features/calendar/Persian.js → dist/features/calendar/Persian.d.ts} +0 -0
  58. package/dist/features/calendar/Persian.js +1 -0
  59. package/dist/features/calendar/Persian.js.map +1 -0
  60. package/dist/generated/assets/cldr/ar.json +799 -1
  61. package/dist/generated/assets/cldr/ar_EG.json +799 -1
  62. package/dist/generated/assets/cldr/ar_SA.json +799 -1
  63. package/dist/generated/assets/cldr/bg.json +764 -1
  64. package/dist/generated/assets/cldr/ca.json +798 -1
  65. package/dist/generated/assets/cldr/cs.json +797 -1
  66. package/dist/generated/assets/cldr/cy.json +729 -1
  67. package/dist/generated/assets/cldr/da.json +764 -1
  68. package/dist/generated/assets/cldr/de.json +798 -1
  69. package/dist/generated/assets/cldr/de_AT.json +798 -1
  70. package/dist/generated/assets/cldr/de_CH.json +798 -1
  71. package/dist/generated/assets/cldr/el.json +697 -1
  72. package/dist/generated/assets/cldr/el_CY.json +697 -1
  73. package/dist/generated/assets/cldr/en.json +763 -1
  74. package/dist/generated/assets/cldr/en_AU.json +764 -2
  75. package/dist/generated/assets/cldr/en_GB.json +763 -1
  76. package/dist/generated/assets/cldr/en_HK.json +763 -1
  77. package/dist/generated/assets/cldr/en_IE.json +763 -1
  78. package/dist/generated/assets/cldr/en_IN.json +763 -1
  79. package/dist/generated/assets/cldr/en_NZ.json +763 -1
  80. package/dist/generated/assets/cldr/en_PG.json +763 -1
  81. package/dist/generated/assets/cldr/en_SG.json +763 -1
  82. package/dist/generated/assets/cldr/en_ZA.json +763 -1
  83. package/dist/generated/assets/cldr/es.json +730 -1
  84. package/dist/generated/assets/cldr/es_AR.json +730 -1
  85. package/dist/generated/assets/cldr/es_BO.json +733 -4
  86. package/dist/generated/assets/cldr/es_CL.json +733 -4
  87. package/dist/generated/assets/cldr/es_CO.json +730 -1
  88. package/dist/generated/assets/cldr/es_MX.json +733 -4
  89. package/dist/generated/assets/cldr/es_PE.json +733 -4
  90. package/dist/generated/assets/cldr/es_UY.json +733 -4
  91. package/dist/generated/assets/cldr/es_VE.json +732 -3
  92. package/dist/generated/assets/cldr/et.json +763 -1
  93. package/dist/generated/assets/cldr/fa.json +765 -1
  94. package/dist/generated/assets/cldr/fi.json +797 -1
  95. package/dist/generated/assets/cldr/fr.json +763 -1
  96. package/dist/generated/assets/cldr/fr_BE.json +763 -1
  97. package/dist/generated/assets/cldr/fr_CA.json +763 -1
  98. package/dist/generated/assets/cldr/fr_CH.json +763 -1
  99. package/dist/generated/assets/cldr/fr_LU.json +763 -1
  100. package/dist/generated/assets/cldr/he.json +798 -1
  101. package/dist/generated/assets/cldr/hi.json +730 -1
  102. package/dist/generated/assets/cldr/hr.json +763 -1
  103. package/dist/generated/assets/cldr/hu.json +831 -1
  104. package/dist/generated/assets/cldr/id.json +763 -1
  105. package/dist/generated/assets/cldr/it.json +763 -1
  106. package/dist/generated/assets/cldr/it_CH.json +763 -1
  107. package/dist/generated/assets/cldr/ja.json +797 -1
  108. package/dist/generated/assets/cldr/kk.json +763 -1
  109. package/dist/generated/assets/cldr/ko.json +797 -1
  110. package/dist/generated/assets/cldr/lt.json +763 -1
  111. package/dist/generated/assets/cldr/lv.json +763 -1
  112. package/dist/generated/assets/cldr/ms.json +731 -1
  113. package/dist/generated/assets/cldr/nb.json +764 -1
  114. package/dist/generated/assets/cldr/nl.json +730 -1
  115. package/dist/generated/assets/cldr/nl_BE.json +730 -1
  116. package/dist/generated/assets/cldr/pl.json +797 -1
  117. package/dist/generated/assets/cldr/pt.json +763 -1
  118. package/dist/generated/assets/cldr/pt_PT.json +763 -1
  119. package/dist/generated/assets/cldr/ro.json +763 -1
  120. package/dist/generated/assets/cldr/ru.json +763 -1
  121. package/dist/generated/assets/cldr/ru_UA.json +763 -1
  122. package/dist/generated/assets/cldr/sk.json +797 -1
  123. package/dist/generated/assets/cldr/sl.json +797 -1
  124. package/dist/generated/assets/cldr/sr.json +763 -1
  125. package/dist/generated/assets/cldr/sr_Latn.json +763 -1
  126. package/dist/generated/assets/cldr/sv.json +764 -1
  127. package/dist/generated/assets/cldr/th.json +831 -1
  128. package/dist/generated/assets/cldr/tr.json +831 -1
  129. package/dist/generated/assets/cldr/uk.json +763 -1
  130. package/dist/generated/assets/cldr/vi.json +763 -1
  131. package/dist/generated/assets/cldr/zh_CN.json +799 -2
  132. package/dist/generated/assets/cldr/zh_HK.json +799 -2
  133. package/dist/generated/assets/cldr/zh_SG.json +799 -2
  134. package/dist/generated/assets/cldr/zh_TW.json +798 -1
  135. package/dist/generated/json-imports/LocaleData-static.js +2 -1
  136. package/dist/generated/json-imports/LocaleData.js +2 -1
  137. package/dist/getCachedLocaleDataInstance.d.ts +4 -0
  138. package/dist/getCachedLocaleDataInstance.js +6 -9
  139. package/dist/getCachedLocaleDataInstance.js.map +1 -0
  140. package/dist/locale/getLocaleData.d.ts +11 -0
  141. package/dist/locale/getLocaleData.js +13 -17
  142. package/dist/locale/getLocaleData.js.map +1 -0
  143. package/dist/sap/base/Log.js +28 -37
  144. package/dist/sap/base/assert.js +5 -10
  145. package/dist/sap/base/util/LoaderExtensions.d.ts +4 -0
  146. package/dist/sap/base/util/LoaderExtensions.js +9 -12
  147. package/dist/sap/base/util/LoaderExtensions.js.map +1 -0
  148. package/dist/sap/base/util/deepEqual.js +1 -5
  149. package/dist/sap/ui/base/Object.js +26 -2
  150. package/dist/sap/ui/core/Configuration.d.ts +17 -0
  151. package/dist/sap/ui/core/Configuration.js +20 -0
  152. package/dist/sap/ui/core/Configuration.js.map +1 -0
  153. package/dist/sap/ui/core/Core.d.ts +26 -0
  154. package/dist/sap/ui/core/Core.js +7 -32
  155. package/dist/sap/ui/core/Core.js.map +1 -0
  156. package/dist/sap/ui/core/FormatSettings.d.ts +10 -0
  157. package/dist/sap/ui/core/FormatSettings.js +13 -0
  158. package/dist/sap/ui/core/FormatSettings.js.map +1 -0
  159. package/dist/sap/ui/core/Locale.js +15 -0
  160. package/dist/sap/ui/core/LocaleData.js +109 -1503
  161. package/dist/sap/ui/core/date/Buddhist.js +0 -6
  162. package/dist/sap/ui/core/date/CalendarUtils.js +36 -0
  163. package/dist/sap/ui/core/date/CalendarWeekNumbering.js +7 -0
  164. package/dist/sap/ui/core/date/Islamic.js +3 -3
  165. package/dist/sap/ui/core/date/Japanese.js +4 -4
  166. package/dist/sap/ui/core/date/UniversalDate.js +79 -22
  167. package/dist/sap/ui/core/format/DateFormat.js +497 -198
  168. package/dist/sap/ui/core/format/TimezoneUtil.js +94 -0
  169. package/package-scripts.js +8 -10
  170. package/package.json +7 -14
  171. package/src/{Assets-static.js → Assets-static.ts} +0 -0
  172. package/src/{Assets.js → Assets.ts} +0 -0
  173. package/src/DateFormat.ts +8 -0
  174. package/src/LocaleData.ts +8 -0
  175. package/src/dates/{CalendarDate.js → CalendarDate.ts} +43 -34
  176. package/src/dates/{ExtremeDates.js → ExtremeDates.ts} +6 -5
  177. package/src/dates/UniversalDate.ts +51 -0
  178. package/src/dates/{calculateWeekNumber.js → calculateWeekNumber.ts} +5 -3
  179. package/src/dates/convertMonthNumbersToMonthNames.ts +34 -0
  180. package/src/dates/getDaysInMonth.ts +11 -0
  181. package/src/dates/{getRoundedTimestamp.js → getRoundedTimestamp.ts} +3 -3
  182. package/src/dates/getTodayUTCTimestamp.ts +10 -0
  183. package/src/dates/{modifyDateBy.js → modifyDateBy.ts} +1 -1
  184. package/src/dates/transformDateToSecondaryType.ts +21 -0
  185. package/src/features/calendar/Buddhist.ts +1 -0
  186. package/src/features/calendar/Gregorian.ts +1 -0
  187. package/src/features/calendar/Islamic.ts +1 -0
  188. package/src/features/calendar/Japanese.ts +1 -0
  189. package/src/features/calendar/Persian.ts +1 -0
  190. package/src/getCachedLocaleDataInstance.ts +15 -0
  191. package/src/locale/{getLocaleData.js → getLocaleData.ts} +9 -8
  192. package/src/sap/base/util/{LoaderExtensions.js → LoaderExtensions.ts} +1 -1
  193. package/src/sap/ui/core/{Core.js → Configuration.ts} +5 -21
  194. package/src/sap/ui/core/Core.ts +15 -0
  195. package/src/sap/ui/core/FormatSettings.ts +15 -0
  196. package/tsconfig.json +13 -0
  197. package/used-modules.txt +4 -1
  198. package/hash.txt +0 -1
  199. package/src/DateFormat.js +0 -3
  200. package/src/LocaleData.js +0 -3
  201. package/src/dates/getTodayUTCTimestamp.js +0 -9
  202. package/src/getCachedLocaleDataInstance.js +0 -13
@@ -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,17 +438,32 @@ 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
469
  parseTZ: function (sValue, bColonSeparated) {
@@ -369,7 +485,7 @@ var oParseHelper = {
369
485
  }
370
486
  return {
371
487
  length: iLength,
372
- tzDiff: (iTZDiff + 60 * iTZDiffHour) * iTZFactor
488
+ tzDiff: (iTZDiff + 60 * iTZDiffHour) * 60 * iTZFactor
373
489
  };
374
490
  },
375
491
  checkValid: function (sType, bPartInvalid, oFormat) {
@@ -381,7 +497,7 @@ var oParseHelper = {
381
497
  DateFormat.prototype.oSymbols = {
382
498
  '': {
383
499
  name: 'text',
384
- format: function (oField, oDate, bUTC, oFormat) {
500
+ format: function (oField, oDate) {
385
501
  return oField.value;
386
502
  },
387
503
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -425,7 +541,7 @@ DateFormat.prototype.oSymbols = {
425
541
  'G': {
426
542
  name: 'era',
427
543
  format: function (oField, oDate, bUTC, oFormat) {
428
- var iEra = bUTC ? oDate.getUTCEra() : oDate.getEra();
544
+ var iEra = oDate.getUTCEra();
429
545
  if (oField.digits <= 3) {
430
546
  return oFormat.aErasAbbrev[iEra];
431
547
  } else if (oField.digits === 4) {
@@ -442,11 +558,11 @@ DateFormat.prototype.oSymbols = {
442
558
  ];
443
559
  for (var i = 0; i < aErasVariants.length; i++) {
444
560
  var aVariants = aErasVariants[i];
445
- var oFound = oParseHelper.findEntry(sValue, aVariants);
561
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
446
562
  if (oFound.index !== -1) {
447
563
  return {
448
564
  era: oFound.index,
449
- length: oFound.value.length
565
+ length: oFound.length
450
566
  };
451
567
  }
452
568
  }
@@ -459,7 +575,7 @@ DateFormat.prototype.oSymbols = {
459
575
  'y': {
460
576
  name: 'year',
461
577
  format: function (oField, oDate, bUTC, oFormat) {
462
- var iYear = bUTC ? oDate.getUTCFullYear() : oDate.getFullYear();
578
+ var iYear = oDate.getUTCFullYear();
463
579
  var sYear = String(iYear);
464
580
  var sCalendarType = oFormat.oFormatOptions.calendarType;
465
581
  if (oField.digits == 2 && sYear.length > 2) {
@@ -482,7 +598,7 @@ DateFormat.prototype.oSymbols = {
482
598
  }
483
599
  var iYear = parseInt(sPart);
484
600
  if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
485
- 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;
486
602
  if (iYearDiff < -70) {
487
603
  iYear += (iCurrentCentury + 1) * 100;
488
604
  } else if (iYearDiff < 30) {
@@ -501,7 +617,7 @@ DateFormat.prototype.oSymbols = {
501
617
  'Y': {
502
618
  name: 'weekYear',
503
619
  format: function (oField, oDate, bUTC, oFormat) {
504
- var oWeek = bUTC ? oDate.getUTCWeek() : oDate.getWeek();
620
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
505
621
  var iWeekYear = oWeek.year;
506
622
  var sWeekYear = String(iWeekYear);
507
623
  var sCalendarType = oFormat.oFormatOptions.calendarType;
@@ -524,9 +640,9 @@ DateFormat.prototype.oSymbols = {
524
640
  sPart = oParseHelper.findNumbers(sValue, oPart.digits);
525
641
  }
526
642
  var iYear = parseInt(sPart);
527
- var iWeekYear;
643
+ var iWeekYear = iYear;
528
644
  if (sCalendarType != CalendarType.Japanese && sPart.length <= 2) {
529
- 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;
530
646
  if (iYearDiff < -70) {
531
647
  iWeekYear += (iCurrentCentury + 1) * 100;
532
648
  } else if (iYearDiff < 30) {
@@ -546,7 +662,7 @@ DateFormat.prototype.oSymbols = {
546
662
  'M': {
547
663
  name: 'month',
548
664
  format: function (oField, oDate, bUTC, oFormat) {
549
- var iMonth = bUTC ? oDate.getUTCMonth() : oDate.getMonth();
665
+ var iMonth = oDate.getUTCMonth();
550
666
  if (oField.digits == 3) {
551
667
  return oFormat.aMonthsAbbrev[iMonth];
552
668
  } else if (oField.digits == 4) {
@@ -579,11 +695,11 @@ DateFormat.prototype.oSymbols = {
579
695
  } else {
580
696
  for (var i = 0; i < aMonthsVariants.length; i++) {
581
697
  var aVariants = aMonthsVariants[i];
582
- var oFound = oParseHelper.findEntry(sValue, aVariants);
698
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
583
699
  if (oFound.index !== -1) {
584
700
  return {
585
701
  month: oFound.index,
586
- length: oFound.value.length
702
+ length: oFound.length
587
703
  };
588
704
  }
589
705
  }
@@ -599,7 +715,7 @@ DateFormat.prototype.oSymbols = {
599
715
  'L': {
600
716
  name: 'monthStandalone',
601
717
  format: function (oField, oDate, bUTC, oFormat) {
602
- var iMonth = bUTC ? oDate.getUTCMonth() : oDate.getMonth();
718
+ var iMonth = oDate.getUTCMonth();
603
719
  if (oField.digits == 3) {
604
720
  return oFormat.aMonthsAbbrevSt[iMonth];
605
721
  } else if (oField.digits == 4) {
@@ -632,11 +748,11 @@ DateFormat.prototype.oSymbols = {
632
748
  } else {
633
749
  for (var i = 0; i < aMonthsVariants.length; i++) {
634
750
  var aVariants = aMonthsVariants[i];
635
- var oFound = oParseHelper.findEntry(sValue, aVariants);
751
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
636
752
  if (oFound.index !== -1) {
637
753
  return {
638
754
  month: oFound.index,
639
- length: oFound.value.length
755
+ length: oFound.length
640
756
  };
641
757
  }
642
758
  }
@@ -652,7 +768,7 @@ DateFormat.prototype.oSymbols = {
652
768
  'w': {
653
769
  name: 'weekInYear',
654
770
  format: function (oField, oDate, bUTC, oFormat) {
655
- var oWeek = bUTC ? oDate.getUTCWeek() : oDate.getWeek();
771
+ var oWeek = oDate.getUTCWeek(oFormat.oLocale, getCalendarWeekParameter(oFormat.oFormatOptions));
656
772
  var iWeek = oWeek.week;
657
773
  var sWeek = String(iWeek + 1);
658
774
  if (oField.digits < 3) {
@@ -674,11 +790,11 @@ DateFormat.prototype.oSymbols = {
674
790
  bValid = oParseHelper.checkValid(oPart.type, !sPart, oFormat);
675
791
  } else {
676
792
  sPart = oFormat.oLocaleData.getCalendarWeek(oPart.digits === 3 ? 'narrow' : 'wide');
677
- sPart = sPart.replace('{0}', '[0-9]+');
793
+ sPart = sPart.replace('{0}', '([0-9]+)');
678
794
  var rWeekNumber = new RegExp(sPart), oResult = rWeekNumber.exec(sValue);
679
795
  if (oResult) {
680
796
  iLength = oResult[0].length;
681
- iWeek = parseInt(oResult[0]) - 1;
797
+ iWeek = parseInt(oResult[oResult.length - 1]) - 1;
682
798
  } else {
683
799
  bValid = oParseHelper.checkValid(oPart.type, true, oFormat);
684
800
  }
@@ -692,7 +808,7 @@ DateFormat.prototype.oSymbols = {
692
808
  },
693
809
  'W': {
694
810
  name: 'weekInMonth',
695
- format: function (oField, oDate, bUTC, oFormat) {
811
+ format: function (oField, oDate) {
696
812
  return '';
697
813
  },
698
814
  parse: function () {
@@ -701,7 +817,7 @@ DateFormat.prototype.oSymbols = {
701
817
  },
702
818
  'D': {
703
819
  name: 'dayInYear',
704
- format: function (oField, oDate, bUTC, oFormat) {
820
+ format: function (oField, oDate) {
705
821
  },
706
822
  parse: function () {
707
823
  return {};
@@ -709,8 +825,8 @@ DateFormat.prototype.oSymbols = {
709
825
  },
710
826
  'd': {
711
827
  name: 'day',
712
- format: function (oField, oDate, bUTC, oFormat) {
713
- var iDate = bUTC ? oDate.getUTCDate() : oDate.getDate();
828
+ format: function (oField, oDate) {
829
+ var iDate = oDate.getUTCDate();
714
830
  return String(iDate).padStart(oField.digits, '0');
715
831
  },
716
832
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -730,7 +846,7 @@ DateFormat.prototype.oSymbols = {
730
846
  'Q': {
731
847
  name: 'quarter',
732
848
  format: function (oField, oDate, bUTC, oFormat) {
733
- var iQuarter = bUTC ? oDate.getUTCQuarter() : oDate.getQuarter();
849
+ var iQuarter = oDate.getUTCQuarter();
734
850
  if (oField.digits == 3) {
735
851
  return oFormat.aQuartersAbbrev[iQuarter];
736
852
  } else if (oField.digits == 4) {
@@ -763,11 +879,11 @@ DateFormat.prototype.oSymbols = {
763
879
  } else {
764
880
  for (var i = 0; i < aQuartersVariants.length; i++) {
765
881
  var aVariants = aQuartersVariants[i];
766
- var oFound = oParseHelper.findEntry(sValue, aVariants);
882
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
767
883
  if (oFound.index !== -1) {
768
884
  return {
769
885
  quarter: oFound.index,
770
- length: oFound.value.length
886
+ length: oFound.length
771
887
  };
772
888
  }
773
889
  }
@@ -783,7 +899,7 @@ DateFormat.prototype.oSymbols = {
783
899
  'q': {
784
900
  name: 'quarterStandalone',
785
901
  format: function (oField, oDate, bUTC, oFormat) {
786
- var iQuarter = bUTC ? oDate.getUTCQuarter() : oDate.getQuarter();
902
+ var iQuarter = oDate.getUTCQuarter();
787
903
  if (oField.digits == 3) {
788
904
  return oFormat.aQuartersAbbrevSt[iQuarter];
789
905
  } else if (oField.digits == 4) {
@@ -816,11 +932,11 @@ DateFormat.prototype.oSymbols = {
816
932
  } else {
817
933
  for (var i = 0; i < aQuartersVariants.length; i++) {
818
934
  var aVariants = aQuartersVariants[i];
819
- var oFound = oParseHelper.findEntry(sValue, aVariants);
935
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
820
936
  if (oFound.index !== -1) {
821
937
  return {
822
938
  quarter: oFound.index,
823
- length: oFound.value.length
939
+ length: oFound.length
824
940
  };
825
941
  }
826
942
  }
@@ -835,7 +951,7 @@ DateFormat.prototype.oSymbols = {
835
951
  },
836
952
  'F': {
837
953
  name: 'dayOfWeekInMonth',
838
- format: function (oField, oDate, bUTC, oFormat) {
954
+ format: function (oField, oDate, oFormat) {
839
955
  return '';
840
956
  },
841
957
  parse: function () {
@@ -845,7 +961,7 @@ DateFormat.prototype.oSymbols = {
845
961
  'E': {
846
962
  name: 'dayNameInWeek',
847
963
  format: function (oField, oDate, bUTC, oFormat) {
848
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
964
+ var iDay = oDate.getUTCDay();
849
965
  if (oField.digits < 4) {
850
966
  return oFormat.aDaysAbbrev[iDay];
851
967
  } else if (oField.digits == 4) {
@@ -869,11 +985,11 @@ DateFormat.prototype.oSymbols = {
869
985
  ];
870
986
  for (var i = 0; i < aDaysVariants.length; i++) {
871
987
  var aVariants = aDaysVariants[i];
872
- var oFound = oParseHelper.findEntry(sValue, aVariants);
988
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
873
989
  if (oFound.index !== -1) {
874
990
  return {
875
991
  dayOfWeek: oFound.index,
876
- length: oFound.value.length
992
+ length: oFound.length
877
993
  };
878
994
  }
879
995
  }
@@ -882,7 +998,7 @@ DateFormat.prototype.oSymbols = {
882
998
  'c': {
883
999
  name: 'dayNameInWeekStandalone',
884
1000
  format: function (oField, oDate, bUTC, oFormat) {
885
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
1001
+ var iDay = oDate.getUTCDay();
886
1002
  if (oField.digits < 4) {
887
1003
  return oFormat.aDaysAbbrevSt[iDay];
888
1004
  } else if (oField.digits == 4) {
@@ -906,11 +1022,11 @@ DateFormat.prototype.oSymbols = {
906
1022
  ];
907
1023
  for (var i = 0; i < aDaysVariants.length; i++) {
908
1024
  var aVariants = aDaysVariants[i];
909
- var oFound = oParseHelper.findEntry(sValue, aVariants);
1025
+ var oFound = oParseHelper.findEntry(sValue, aVariants, oFormat.oLocaleData.sCLDRLocaleId);
910
1026
  if (oFound.index !== -1) {
911
1027
  return {
912
1028
  day: oFound.index,
913
- length: oFound.value.length
1029
+ length: oFound.length
914
1030
  };
915
1031
  }
916
1032
  }
@@ -919,7 +1035,7 @@ DateFormat.prototype.oSymbols = {
919
1035
  'u': {
920
1036
  name: 'dayNumberOfWeek',
921
1037
  format: function (oField, oDate, bUTC, oFormat) {
922
- var iDay = bUTC ? oDate.getUTCDay() : oDate.getDay();
1038
+ var iDay = oDate.getUTCDay();
923
1039
  return oFormat._adaptDayOfWeek(iDay);
924
1040
  },
925
1041
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -933,38 +1049,96 @@ DateFormat.prototype.oSymbols = {
933
1049
  'a': {
934
1050
  name: 'amPmMarker',
935
1051
  format: function (oField, oDate, bUTC, oFormat) {
936
- var iDayPeriod = bUTC ? oDate.getUTCDayPeriod() : oDate.getDayPeriod();
937
- 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];
938
1114
  },
939
1115
  parse: function (sValue, oPart, oFormat, oConfig) {
940
- var bPM;
941
- var iLength;
942
- var sAM = oFormat.aDayPeriods[0], sPM = oFormat.aDayPeriods[1];
943
- var rAMPM = /[aApP](?:\.)?[mM](?:\.)?/;
944
- var aMatch = sValue.match(rAMPM);
945
- var bVariant = aMatch && aMatch.index === 0;
946
- if (bVariant) {
947
- sValue = aMatch[0].replace(/\./g, '').toLowerCase() + sValue.substring(aMatch[0].length);
948
- sAM = sAM.replace(/\./g, '').toLowerCase();
949
- sPM = sPM.replace(/\./g, '').toLowerCase();
950
- }
951
- if (sValue.indexOf(sAM) === 0) {
952
- bPM = false;
953
- iLength = bVariant ? aMatch[0].length : sAM.length;
954
- } else if (sValue.indexOf(sPM) === 0) {
955
- bPM = true;
956
- 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
+ }
957
1134
  }
958
- return {
959
- pm: bPM,
960
- length: iLength
961
- };
1135
+ return { valid: false };
962
1136
  }
963
1137
  },
964
1138
  'H': {
965
1139
  name: 'hour0_23',
966
- format: function (oField, oDate, bUTC, oFormat) {
967
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1140
+ format: function (oField, oDate) {
1141
+ var iHours = oDate.getUTCHours();
968
1142
  return String(iHours).padStart(oField.digits, '0');
969
1143
  },
970
1144
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -984,8 +1158,8 @@ DateFormat.prototype.oSymbols = {
984
1158
  },
985
1159
  'k': {
986
1160
  name: 'hour1_24',
987
- format: function (oField, oDate, bUTC, oFormat) {
988
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1161
+ format: function (oField, oDate) {
1162
+ var iHours = oDate.getUTCHours();
989
1163
  var sHours = iHours === 0 ? '24' : String(iHours);
990
1164
  return sHours.padStart(oField.digits, '0');
991
1165
  },
@@ -1009,8 +1183,8 @@ DateFormat.prototype.oSymbols = {
1009
1183
  },
1010
1184
  'K': {
1011
1185
  name: 'hour0_11',
1012
- format: function (oField, oDate, bUTC, oFormat) {
1013
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1186
+ format: function (oField, oDate) {
1187
+ var iHours = oDate.getUTCHours();
1014
1188
  var sHours = String(iHours > 11 ? iHours - 12 : iHours);
1015
1189
  return sHours.padStart(oField.digits, '0');
1016
1190
  },
@@ -1031,8 +1205,8 @@ DateFormat.prototype.oSymbols = {
1031
1205
  },
1032
1206
  'h': {
1033
1207
  name: 'hour1_12',
1034
- format: function (oField, oDate, bUTC, oFormat) {
1035
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1208
+ format: function (oField, oDate) {
1209
+ var iHours = oDate.getUTCHours();
1036
1210
  var sHours;
1037
1211
  if (iHours > 12) {
1038
1212
  sHours = String(iHours - 12);
@@ -1065,8 +1239,8 @@ DateFormat.prototype.oSymbols = {
1065
1239
  },
1066
1240
  'm': {
1067
1241
  name: 'minute',
1068
- format: function (oField, oDate, bUTC, oFormat) {
1069
- var iMinutes = bUTC ? oDate.getUTCMinutes() : oDate.getMinutes();
1242
+ format: function (oField, oDate) {
1243
+ var iMinutes = oDate.getUTCMinutes();
1070
1244
  return String(iMinutes).padStart(oField.digits, '0');
1071
1245
  },
1072
1246
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -1086,8 +1260,8 @@ DateFormat.prototype.oSymbols = {
1086
1260
  },
1087
1261
  's': {
1088
1262
  name: 'second',
1089
- format: function (oField, oDate, bUTC, oFormat) {
1090
- var iSeconds = bUTC ? oDate.getUTCSeconds() : oDate.getSeconds();
1263
+ format: function (oField, oDate) {
1264
+ var iSeconds = oDate.getUTCSeconds();
1091
1265
  return String(iSeconds).padStart(oField.digits, '0');
1092
1266
  },
1093
1267
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -1107,8 +1281,8 @@ DateFormat.prototype.oSymbols = {
1107
1281
  },
1108
1282
  'S': {
1109
1283
  name: 'fractionalsecond',
1110
- format: function (oField, oDate, bUTC, oFormat) {
1111
- var iMilliseconds = bUTC ? oDate.getUTCMilliseconds() : oDate.getMilliseconds();
1284
+ format: function (oField, oDate) {
1285
+ var iMilliseconds = oDate.getUTCMilliseconds();
1112
1286
  var sMilliseconds = String(iMilliseconds);
1113
1287
  var sFractionalseconds = sMilliseconds.padStart(3, '0');
1114
1288
  sFractionalseconds = sFractionalseconds.substr(0, oField.digits);
@@ -1129,17 +1303,18 @@ DateFormat.prototype.oSymbols = {
1129
1303
  },
1130
1304
  'z': {
1131
1305
  name: 'timezoneGeneral',
1132
- format: function (oField, oDate, bUTC, oFormat) {
1306
+ format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1133
1307
  if (oField.digits > 3 && oDate.getTimezoneLong && oDate.getTimezoneLong()) {
1134
1308
  return oDate.getTimezoneLong();
1135
1309
  } else if (oDate.getTimezoneShort && oDate.getTimezoneShort()) {
1136
1310
  return oDate.getTimezoneShort();
1137
1311
  }
1312
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1138
1313
  var sTimeZone = 'GMT';
1139
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1140
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1314
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1315
+ var bPositiveOffset = iTimezoneOffset > 0;
1141
1316
  var iHourOffset = Math.floor(iTZOffset / 60);
1142
- var iMinuteOffset = iTZOffset % 60;
1317
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1143
1318
  if (!bUTC && iTZOffset != 0) {
1144
1319
  sTimeZone += bPositiveOffset ? '-' : '+';
1145
1320
  sTimeZone += String(iHourOffset).padStart(2, '0');
@@ -1162,7 +1337,7 @@ DateFormat.prototype.oSymbols = {
1162
1337
  iLength = 1;
1163
1338
  iTZDiff = 0;
1164
1339
  } else {
1165
- 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!' };
1166
1341
  }
1167
1342
  if (sValue.charAt(0) !== 'Z') {
1168
1343
  var oParsedTZ = oParseHelper.parseTZ(sValue.substr(iLength), true);
@@ -1177,11 +1352,12 @@ DateFormat.prototype.oSymbols = {
1177
1352
  },
1178
1353
  'Z': {
1179
1354
  name: 'timezoneRFC822',
1180
- format: function (oField, oDate, bUTC, oFormat) {
1181
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1182
- 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;
1183
1359
  var iHourOffset = Math.floor(iTZOffset / 60);
1184
- var iMinuteOffset = iTZOffset % 60;
1360
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1185
1361
  var sTimeZone = '';
1186
1362
  if (!bUTC) {
1187
1363
  sTimeZone += bPositiveOffset ? '-' : '+';
@@ -1196,11 +1372,12 @@ DateFormat.prototype.oSymbols = {
1196
1372
  },
1197
1373
  'X': {
1198
1374
  name: 'timezoneISO8601',
1199
- format: function (oField, oDate, bUTC, oFormat) {
1200
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1201
- 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;
1202
1379
  var iHourOffset = Math.floor(iTZOffset / 60);
1203
- var iMinuteOffset = iTZOffset % 60;
1380
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1204
1381
  var sTimeZone = '';
1205
1382
  if (!bUTC && iTZOffset != 0) {
1206
1383
  sTimeZone += bPositiveOffset ? '-' : '+';
@@ -1226,11 +1403,52 @@ DateFormat.prototype.oSymbols = {
1226
1403
  return oParseHelper.parseTZ(sValue, oPart.digits === 3 || oPart.digits === 5);
1227
1404
  }
1228
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
+ }
1444
+ }
1445
+ return oTimezoneParsed;
1446
+ }
1229
1447
  }
1230
1448
  };
1231
- DateFormat.prototype._format = function (oJSDate, bUTC) {
1449
+ DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1232
1450
  if (this.oFormatOptions.relative) {
1233
- var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange);
1451
+ var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange, sTimezone);
1234
1452
  if (sRes) {
1235
1453
  return sRes;
1236
1454
  }
@@ -1241,10 +1459,10 @@ DateFormat.prototype._format = function (oJSDate, bUTC) {
1241
1459
  for (var i = 0; i < this.aFormatArray.length; i++) {
1242
1460
  oPart = this.aFormatArray[i];
1243
1461
  sSymbol = oPart.symbol || '';
1244
- aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this));
1462
+ aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this, sTimezone));
1245
1463
  }
1246
1464
  sResult = aBuffer.join('');
1247
- if (Core.getConfiguration().getOriginInfo()) {
1465
+ if (Configuration.getOriginInfo()) {
1248
1466
  sResult = new String(sResult);
1249
1467
  sResult.originInfo = {
1250
1468
  source: 'Common Locale Data Repository',
@@ -1256,10 +1474,21 @@ DateFormat.prototype._format = function (oJSDate, bUTC) {
1256
1474
  return sResult;
1257
1475
  };
1258
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
+ }
1259
1487
  var sCalendarType = this.oFormatOptions.calendarType, sResult;
1260
1488
  if (bUTC === undefined) {
1261
1489
  bUTC = this.oFormatOptions.UTC;
1262
1490
  }
1491
+ sTimezone = sTimezone || Configuration.getTimezone();
1263
1492
  if (Array.isArray(vJSDate)) {
1264
1493
  if (!this.oFormatOptions.interval) {
1265
1494
  Log.error('Non-interval DateFormat can\'t format more than one date instance.');
@@ -1269,27 +1498,30 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1269
1498
  Log.error('Interval DateFormat can only format with 2 date instances but ' + vJSDate.length + ' is given.');
1270
1499
  return '';
1271
1500
  }
1501
+ vJSDate = vJSDate.map(function (oJSDate) {
1502
+ return convertToTimezone(oJSDate, sTimezone, bUTC);
1503
+ });
1272
1504
  if (this.oFormatOptions.singleIntervalValue) {
1273
1505
  if (vJSDate[0] === null) {
1274
1506
  Log.error('First date instance which is passed to the interval DateFormat shouldn\'t be null.');
1275
1507
  return '';
1276
1508
  }
1277
1509
  if (vJSDate[1] === null) {
1278
- sResult = this._format(vJSDate[0], bUTC);
1510
+ sResult = this._format(vJSDate[0], bUTC, sTimezone);
1279
1511
  }
1280
1512
  }
1281
1513
  if (sResult === undefined) {
1282
- var bValid = vJSDate.every(function (oJSDate) {
1283
- return oJSDate && !isNaN(oJSDate.getTime());
1284
- });
1285
- if (!bValid) {
1514
+ if (!vJSDate.every(isValidDateObject)) {
1286
1515
  Log.error('At least one date instance which is passed to the interval DateFormat isn\'t valid.');
1287
1516
  return '';
1288
1517
  }
1289
1518
  sResult = this._formatInterval(vJSDate, bUTC);
1290
1519
  }
1291
1520
  } else {
1292
- 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
+ }
1293
1525
  Log.error('The given date instance isn\'t valid.');
1294
1526
  return '';
1295
1527
  }
@@ -1297,7 +1529,8 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1297
1529
  Log.error('Interval DateFormat expects an array with two dates for the first argument but only one date is given.');
1298
1530
  return '';
1299
1531
  }
1300
- sResult = this._format(vJSDate, bUTC);
1532
+ vJSDate = convertToTimezone(vJSDate, sTimezone, bUTC);
1533
+ sResult = this._format(vJSDate, bUTC, sTimezone);
1301
1534
  }
1302
1535
  if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1303
1536
  sResult = sResult.replace(/(^|[^\d])1年/g, '$1元年');
@@ -1317,7 +1550,7 @@ DateFormat.prototype._formatInterval = function (aJSDates, bUTC) {
1317
1550
  var oDiffField = this._getGreatestDiffField([
1318
1551
  oFromDate,
1319
1552
  oToDate
1320
- ], bUTC);
1553
+ ]);
1321
1554
  if (!oDiffField) {
1322
1555
  return this._format(aJSDates[0], bUTC);
1323
1556
  }
@@ -1350,10 +1583,10 @@ var mFieldToGroup = {
1350
1583
  Minutes: 'Minute',
1351
1584
  Seconds: 'Second'
1352
1585
  };
1353
- DateFormat.prototype._getGreatestDiffField = function (aDates, bUTC) {
1586
+ DateFormat.prototype._getGreatestDiffField = function (aDates) {
1354
1587
  var bDiffFound = false, mDiff = {};
1355
1588
  this.aIntervalCompareFields.forEach(function (sField) {
1356
- 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]);
1357
1590
  if (!deepEqual(vFromValue, vToValue)) {
1358
1591
  bDiffFound = true;
1359
1592
  mDiff[sFieldGroup] = true;
@@ -1364,9 +1597,12 @@ DateFormat.prototype._getGreatestDiffField = function (aDates, bUTC) {
1364
1597
  }
1365
1598
  return null;
1366
1599
  };
1367
- DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1368
- var iIndex = 0, oPart, sSubValue, oResult;
1369
- 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
+ };
1370
1606
  var oParseConf = {
1371
1607
  formatArray: aFormatArray,
1372
1608
  dateValue: oDateValue,
@@ -1376,7 +1612,10 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1376
1612
  sSubValue = sValue.substr(iIndex);
1377
1613
  oPart = aFormatArray[i];
1378
1614
  oParseConf.index = i;
1379
- 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
+ }
1380
1619
  oDateValue = extend(oDateValue, oResult);
1381
1620
  if (oResult.valid === false) {
1382
1621
  break;
@@ -1384,7 +1623,12 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1384
1623
  iIndex += oResult.length || 0;
1385
1624
  }
1386
1625
  oDateValue.index = iIndex;
1387
- 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) {
1388
1632
  oDateValue.hour += 12;
1389
1633
  }
1390
1634
  if (oDateValue.dayNumberOfWeek === undefined && oDateValue.dayOfWeek !== undefined) {
@@ -1396,7 +1640,7 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1396
1640
  }
1397
1641
  return oDateValue;
1398
1642
  };
1399
- DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bStrict) {
1643
+ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bStrict, sTimezone) {
1400
1644
  var aDateValues, iRepeat, oDateValue;
1401
1645
  this.intervalPatterns.some(function (sPattern) {
1402
1646
  var aFormatArray = this.parseCldrDatePattern(sPattern);
@@ -1408,7 +1652,7 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1408
1652
  }
1409
1653
  }
1410
1654
  if (iRepeat === undefined) {
1411
- oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict);
1655
+ oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict, sTimezone);
1412
1656
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1413
1657
  oDateValue.valid = false;
1414
1658
  }
@@ -1422,13 +1666,13 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1422
1666
  return true;
1423
1667
  } else {
1424
1668
  aDateValues = [];
1425
- oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict);
1669
+ oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict, sTimezone);
1426
1670
  if (oDateValue.valid === false) {
1427
1671
  return;
1428
1672
  }
1429
1673
  aDateValues.push(oDateValue);
1430
1674
  var iLength = oDateValue.index;
1431
- oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict);
1675
+ oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict, sTimezone);
1432
1676
  if (oDateValue.index === 0 || oDateValue.index + iLength < sValue.length) {
1433
1677
  oDateValue.valid = false;
1434
1678
  }
@@ -1441,65 +1685,62 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1441
1685
  }.bind(this));
1442
1686
  return aDateValues;
1443
1687
  };
1444
- 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
+ }
1445
1709
  var oDate, iYear = typeof oDateValue.year === 'number' ? oDateValue.year : 1970;
1446
- if (oDateValue.valid) {
1447
- if (bUTC || oDateValue.tzDiff !== undefined) {
1448
- oDate = UniversalDate.getInstance(new Date(0), sCalendarType);
1449
- oDate.setUTCEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1450
- oDate.setUTCFullYear(iYear);
1451
- oDate.setUTCMonth(oDateValue.month || 0);
1452
- oDate.setUTCDate(oDateValue.day || 1);
1453
- oDate.setUTCHours(oDateValue.hour || 0);
1454
- oDate.setUTCMinutes(oDateValue.minute || 0);
1455
- oDate.setUTCSeconds(oDateValue.second || 0);
1456
- oDate.setUTCMilliseconds(oDateValue.millisecond || 0);
1457
- if (bStrict && (oDateValue.day || 1) !== oDate.getUTCDate()) {
1458
- oDateValue.valid = false;
1459
- oDate = undefined;
1460
- } else {
1461
- if (oDateValue.tzDiff) {
1462
- oDate.setUTCMinutes((oDateValue.minute || 0) + oDateValue.tzDiff);
1463
- }
1464
- if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1465
- oDate.setUTCWeek({
1466
- year: oDateValue.weekYear || oDateValue.year,
1467
- week: oDateValue.week
1468
- });
1469
- if (oDateValue.dayNumberOfWeek !== undefined) {
1470
- oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1471
- }
1472
- }
1473
- }
1474
- } else {
1475
- oDate = UniversalDate.getInstance(new Date(1970, 0, 1, 0, 0, 0), sCalendarType);
1476
- oDate.setEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1477
- oDate.setFullYear(iYear);
1478
- oDate.setMonth(oDateValue.month || 0);
1479
- oDate.setDate(oDateValue.day || 1);
1480
- oDate.setHours(oDateValue.hour || 0);
1481
- oDate.setMinutes(oDateValue.minute || 0);
1482
- oDate.setSeconds(oDateValue.second || 0);
1483
- oDate.setMilliseconds(oDateValue.millisecond || 0);
1484
- if (bStrict && (oDateValue.day || 1) !== oDate.getDate()) {
1485
- oDateValue.valid = false;
1486
- oDate = undefined;
1487
- } else if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1488
- oDate.setWeek({
1489
- year: oDateValue.weekYear || oDateValue.year,
1490
- week: oDateValue.week
1491
- });
1492
- if (oDateValue.dayNumberOfWeek !== undefined) {
1493
- oDate.setDate(oDate.getDate() + oDateValue.dayNumberOfWeek - 1);
1494
- }
1495
- }
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;
1496
1735
  }
1497
- if (oDateValue.valid) {
1498
- oDate = oDate.getJSDate();
1499
- return oDate;
1736
+ if (sTimezone) {
1737
+ oDateValue.tzDiff = TimezoneUtil.calculateOffset(oDate, sTimezone);
1500
1738
  }
1501
1739
  }
1502
- return null;
1740
+ if (oDateValue.tzDiff) {
1741
+ oDate.setUTCSeconds(oDate.getUTCSeconds() + oDateValue.tzDiff);
1742
+ }
1743
+ return oDate;
1503
1744
  };
1504
1745
  function mergeWithoutOverwrite(object1, object2) {
1505
1746
  if (object1 === object2) {
@@ -1522,13 +1763,33 @@ function isValidDateRange(oStartDate, oEndDate) {
1522
1763
  }
1523
1764
  return true;
1524
1765
  }
1766
+ function isValidDateObject(oDate) {
1767
+ return oDate && typeof oDate.getTime === 'function' && !isNaN(oDate.getTime());
1768
+ }
1525
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
+ }
1526
1789
  sValue = sValue == null ? '' : String(sValue).trim();
1527
1790
  var oDateValue;
1528
1791
  var sCalendarType = this.oFormatOptions.calendarType;
1529
- if (bUTC === undefined) {
1530
- bUTC = this.oFormatOptions.UTC;
1531
- }
1792
+ sTimezone = sTimezone || Configuration.getTimezone();
1532
1793
  if (bStrict === undefined) {
1533
1794
  bStrict = this.oFormatOptions.strictParsing;
1534
1795
  }
@@ -1540,22 +1801,40 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1540
1801
  if (oJSDate) {
1541
1802
  return oJSDate;
1542
1803
  }
1543
- oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict);
1804
+ oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict, sTimezone);
1544
1805
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1545
1806
  oDateValue.valid = false;
1546
1807
  }
1547
- oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict);
1808
+ oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1548
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
+ }
1549
1828
  return oJSDate;
1550
1829
  }
1551
1830
  } else {
1552
- var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict);
1831
+ var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict, sTimezone);
1553
1832
  var oJSDate1, oJSDate2;
1554
1833
  if (aDateValues && aDateValues.length == 2) {
1555
1834
  var oDateValue1 = mergeWithoutOverwrite(aDateValues[0], aDateValues[1]);
1556
1835
  var oDateValue2 = mergeWithoutOverwrite(aDateValues[1], aDateValues[0]);
1557
- oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict);
1558
- 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);
1559
1838
  if (oJSDate1 && oJSDate2) {
1560
1839
  if (this.oFormatOptions.singleIntervalValue && oJSDate1.getTime() === oJSDate2.getTime()) {
1561
1840
  return [
@@ -1581,8 +1860,11 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1581
1860
  if (!this.bIsFallback) {
1582
1861
  var vDate;
1583
1862
  this.aFallbackFormats.every(function (oFallbackFormat) {
1584
- vDate = oFallbackFormat.parse(sValue, bUTC, bStrict);
1863
+ vDate = oFallbackFormat.parse(sValue, bUTCInputParameter, bStrict);
1585
1864
  if (Array.isArray(vDate)) {
1865
+ if (oFallbackFormat.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1866
+ return false;
1867
+ }
1586
1868
  return !(vDate[0] && vDate[1]);
1587
1869
  } else {
1588
1870
  return !vDate;
@@ -1731,23 +2013,20 @@ DateFormat.prototype.parseRelative = function (sValue, bUTC) {
1731
2013
  }
1732
2014
  }
1733
2015
  };
1734
- DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange) {
1735
- 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;
1736
2018
  iDiffSeconds = (oJSDate.getTime() - oToday.getTime()) / 1000;
1737
2019
  if (this.oFormatOptions.relativeScale == 'auto') {
1738
2020
  sScale = this._getScale(iDiffSeconds, this.aRelativeScales);
2021
+ sScale = fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds);
1739
2022
  }
1740
2023
  if (!aRange) {
1741
2024
  aRange = this._mRanges[sScale];
1742
2025
  }
1743
2026
  if (sScale == 'year' || sScale == 'month' || sScale == 'day') {
1744
- oToday = new Date(Date.UTC(oToday.getFullYear(), oToday.getMonth(), oToday.getDate()));
2027
+ oToday = new Date(Date.UTC(oToday.getUTCFullYear(), oToday.getUTCMonth(), oToday.getUTCDate()));
1745
2028
  oDateUTC = new Date(0);
1746
- if (bUTC) {
1747
- oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
1748
- } else {
1749
- oDateUTC.setUTCFullYear(oJSDate.getFullYear(), oJSDate.getMonth(), oJSDate.getDate());
1750
- }
2029
+ oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
1751
2030
  oJSDate = oDateUTC;
1752
2031
  }
1753
2032
  iDiff = this._getDifference(sScale, [
@@ -1815,6 +2094,21 @@ DateFormat.prototype._getScale = function (iDiffSeconds, aScales) {
1815
2094
  }
1816
2095
  return sScale;
1817
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
+ }
1818
2112
  function cutDateFields(oDate, iStartIndex) {
1819
2113
  var aFields = [
1820
2114
  'FullYear',
@@ -1827,21 +2121,21 @@ function cutDateFields(oDate, iStartIndex) {
1827
2121
  ], sMethodName;
1828
2122
  var oDateCopy = new Date(oDate.getTime());
1829
2123
  for (var i = iStartIndex; i < aFields.length; i++) {
1830
- sMethodName = 'set' + aFields[iStartIndex];
2124
+ sMethodName = 'setUTC' + aFields[iStartIndex];
1831
2125
  oDateCopy[sMethodName].apply(oDateCopy, [0]);
1832
2126
  }
1833
2127
  return oDateCopy;
1834
2128
  }
1835
2129
  var mRelativeDiffs = {
1836
2130
  year: function (oFromDate, oToDate) {
1837
- return oToDate.getFullYear() - oFromDate.getFullYear();
2131
+ return oToDate.getUTCFullYear() - oFromDate.getUTCFullYear();
1838
2132
  },
1839
2133
  month: function (oFromDate, oToDate) {
1840
- return oToDate.getMonth() - oFromDate.getMonth() + this.year(oFromDate, oToDate) * 12;
2134
+ return oToDate.getUTCMonth() - oFromDate.getUTCMonth() + this.year(oFromDate, oToDate) * 12;
1841
2135
  },
1842
2136
  week: function (oFromDate, oToDate, oFormat) {
1843
- var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getDay());
1844
- var iToDay = oFormat._adaptDayOfWeek(oToDate.getDay());
2137
+ var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getUTCDay());
2138
+ var iToDay = oFormat._adaptDayOfWeek(oToDate.getUTCDay());
1845
2139
  oFromDate = cutDateFields(oFromDate, 3);
1846
2140
  oToDate = cutDateFields(oToDate, 3);
1847
2141
  return (oToDate.getTime() - oFromDate.getTime() - (iToDay - iFromDay) * oFormat._mScales.day * 1000) / (oFormat._mScales.week * 1000);
@@ -1868,7 +2162,12 @@ var mRelativeDiffs = {
1868
2162
  }
1869
2163
  };
1870
2164
  DateFormat.prototype._adaptDayOfWeek = function (iDayOfWeek) {
1871
- 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
+ }
1872
2171
  var iDayNumberOfWeek = iDayOfWeek - (iFirstDayOfWeek - 1);
1873
2172
  if (iDayNumberOfWeek <= 0) {
1874
2173
  iDayNumberOfWeek += 7;