@ui5/webcomponents-localization 0.0.0-cf069fb29 → 0.0.0-d4d43327a

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 (200) hide show
  1. package/CHANGELOG.md +224 -0
  2. package/README.md +5 -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/dist/features/calendar/Buddhist.js +1 -0
  46. package/dist/features/calendar/Buddhist.js.map +1 -0
  47. package/dist/features/calendar/Gregorian.js +1 -0
  48. package/dist/features/calendar/Gregorian.js.map +1 -0
  49. package/dist/features/calendar/Islamic.js +1 -0
  50. package/dist/features/calendar/Islamic.js.map +1 -0
  51. package/dist/features/calendar/Japanese.js +1 -0
  52. package/dist/features/calendar/Japanese.js.map +1 -0
  53. package/dist/features/calendar/Persian.js +1 -0
  54. package/dist/features/calendar/Persian.js.map +1 -0
  55. package/dist/generated/assets/cldr/ar.json +799 -1
  56. package/dist/generated/assets/cldr/ar_EG.json +799 -1
  57. package/dist/generated/assets/cldr/ar_SA.json +799 -1
  58. package/dist/generated/assets/cldr/bg.json +764 -1
  59. package/dist/generated/assets/cldr/ca.json +798 -1
  60. package/dist/generated/assets/cldr/cs.json +797 -1
  61. package/dist/generated/assets/cldr/cy.json +729 -1
  62. package/dist/generated/assets/cldr/da.json +764 -1
  63. package/dist/generated/assets/cldr/de.json +798 -1
  64. package/dist/generated/assets/cldr/de_AT.json +798 -1
  65. package/dist/generated/assets/cldr/de_CH.json +798 -1
  66. package/dist/generated/assets/cldr/el.json +697 -1
  67. package/dist/generated/assets/cldr/el_CY.json +697 -1
  68. package/dist/generated/assets/cldr/en.json +763 -2
  69. package/dist/generated/assets/cldr/en_AU.json +764 -2
  70. package/dist/generated/assets/cldr/en_GB.json +763 -1
  71. package/dist/generated/assets/cldr/en_HK.json +763 -1
  72. package/dist/generated/assets/cldr/en_IE.json +763 -1
  73. package/dist/generated/assets/cldr/en_IN.json +763 -1
  74. package/dist/generated/assets/cldr/en_NZ.json +763 -1
  75. package/dist/generated/assets/cldr/en_PG.json +763 -1
  76. package/dist/generated/assets/cldr/en_SG.json +763 -1
  77. package/dist/generated/assets/cldr/en_ZA.json +763 -1
  78. package/dist/generated/assets/cldr/es.json +730 -1
  79. package/dist/generated/assets/cldr/es_AR.json +730 -1
  80. package/dist/generated/assets/cldr/es_BO.json +733 -4
  81. package/dist/generated/assets/cldr/es_CL.json +733 -4
  82. package/dist/generated/assets/cldr/es_CO.json +730 -1
  83. package/dist/generated/assets/cldr/es_MX.json +733 -4
  84. package/dist/generated/assets/cldr/es_PE.json +733 -4
  85. package/dist/generated/assets/cldr/es_UY.json +733 -4
  86. package/dist/generated/assets/cldr/es_VE.json +732 -3
  87. package/dist/generated/assets/cldr/et.json +763 -1
  88. package/dist/generated/assets/cldr/fa.json +765 -1
  89. package/dist/generated/assets/cldr/fi.json +797 -1
  90. package/dist/generated/assets/cldr/fr.json +763 -1
  91. package/dist/generated/assets/cldr/fr_BE.json +763 -1
  92. package/dist/generated/assets/cldr/fr_CA.json +763 -1
  93. package/dist/generated/assets/cldr/fr_CH.json +763 -1
  94. package/dist/generated/assets/cldr/fr_LU.json +763 -1
  95. package/dist/generated/assets/cldr/he.json +798 -1
  96. package/dist/generated/assets/cldr/hi.json +730 -1
  97. package/dist/generated/assets/cldr/hr.json +763 -1
  98. package/dist/generated/assets/cldr/hu.json +831 -1
  99. package/dist/generated/assets/cldr/id.json +763 -1
  100. package/dist/generated/assets/cldr/it.json +763 -1
  101. package/dist/generated/assets/cldr/it_CH.json +763 -1
  102. package/dist/generated/assets/cldr/ja.json +797 -1
  103. package/dist/generated/assets/cldr/kk.json +763 -1
  104. package/dist/generated/assets/cldr/ko.json +797 -1
  105. package/dist/generated/assets/cldr/lt.json +763 -1
  106. package/dist/generated/assets/cldr/lv.json +763 -1
  107. package/dist/generated/assets/cldr/ms.json +731 -1
  108. package/dist/generated/assets/cldr/nb.json +764 -1
  109. package/dist/generated/assets/cldr/nl.json +730 -1
  110. package/dist/generated/assets/cldr/nl_BE.json +730 -1
  111. package/dist/generated/assets/cldr/pl.json +797 -1
  112. package/dist/generated/assets/cldr/pt.json +763 -1
  113. package/dist/generated/assets/cldr/pt_PT.json +763 -1
  114. package/dist/generated/assets/cldr/ro.json +763 -1
  115. package/dist/generated/assets/cldr/ru.json +763 -1
  116. package/dist/generated/assets/cldr/ru_UA.json +763 -1
  117. package/dist/generated/assets/cldr/sk.json +797 -1
  118. package/dist/generated/assets/cldr/sl.json +797 -1
  119. package/dist/generated/assets/cldr/sr.json +763 -1
  120. package/dist/generated/assets/cldr/sr_Latn.json +763 -1
  121. package/dist/generated/assets/cldr/sv.json +764 -1
  122. package/dist/generated/assets/cldr/th.json +831 -1
  123. package/dist/generated/assets/cldr/tr.json +831 -1
  124. package/dist/generated/assets/cldr/uk.json +763 -1
  125. package/dist/generated/assets/cldr/vi.json +763 -1
  126. package/dist/generated/assets/cldr/zh_CN.json +799 -2
  127. package/dist/generated/assets/cldr/zh_HK.json +799 -2
  128. package/dist/generated/assets/cldr/zh_SG.json +799 -2
  129. package/dist/generated/assets/cldr/zh_TW.json +798 -1
  130. package/dist/generated/json-imports/LocaleData-static.js +2 -1
  131. package/dist/generated/json-imports/LocaleData.js +2 -1
  132. package/dist/getCachedLocaleDataInstance.d.ts +4 -0
  133. package/dist/getCachedLocaleDataInstance.js +6 -9
  134. package/dist/getCachedLocaleDataInstance.js.map +1 -0
  135. package/dist/locale/getLocaleData.d.ts +11 -0
  136. package/dist/locale/getLocaleData.js +13 -17
  137. package/dist/locale/getLocaleData.js.map +1 -0
  138. package/dist/sap/base/Log.js +28 -29
  139. package/dist/sap/base/assert.js +5 -6
  140. package/dist/sap/base/util/LoaderExtensions.d.ts +4 -0
  141. package/dist/sap/base/util/LoaderExtensions.js +9 -12
  142. package/dist/sap/base/util/LoaderExtensions.js.map +1 -0
  143. package/dist/sap/ui/core/Configuration.d.ts +17 -0
  144. package/dist/sap/ui/core/Configuration.js +20 -0
  145. package/dist/sap/ui/core/Configuration.js.map +1 -0
  146. package/dist/sap/ui/core/Core.d.ts +26 -0
  147. package/dist/sap/ui/core/Core.js +7 -32
  148. package/dist/sap/ui/core/Core.js.map +1 -0
  149. package/dist/sap/ui/core/FormatSettings.d.ts +10 -0
  150. package/dist/sap/ui/core/FormatSettings.js +14 -0
  151. package/dist/sap/ui/core/FormatSettings.js.map +1 -0
  152. package/dist/sap/ui/core/Locale.js +13 -0
  153. package/dist/sap/ui/core/LocaleData.js +107 -6
  154. package/dist/sap/ui/core/date/Buddhist.js +0 -6
  155. package/dist/sap/ui/core/date/CalendarUtils.js +36 -0
  156. package/dist/sap/ui/core/date/CalendarWeekNumbering.js +7 -0
  157. package/dist/sap/ui/core/date/Islamic.js +3 -3
  158. package/dist/sap/ui/core/date/Japanese.js +4 -4
  159. package/dist/sap/ui/core/date/UniversalDate.js +79 -22
  160. package/dist/sap/ui/core/format/DateFormat.js +496 -201
  161. package/dist/sap/ui/core/format/TimezoneUtil.js +94 -0
  162. package/package-scripts.js +5 -7
  163. package/package.json +6 -5
  164. package/src/DateFormat.ts +8 -0
  165. package/src/LocaleData.ts +8 -0
  166. package/src/dates/{CalendarDate.js → CalendarDate.ts} +43 -34
  167. package/src/dates/{ExtremeDates.js → ExtremeDates.ts} +6 -5
  168. package/src/dates/UniversalDate.ts +51 -0
  169. package/src/dates/{calculateWeekNumber.js → calculateWeekNumber.ts} +5 -3
  170. package/src/dates/convertMonthNumbersToMonthNames.ts +34 -0
  171. package/src/dates/getDaysInMonth.ts +11 -0
  172. package/src/dates/{getRoundedTimestamp.js → getRoundedTimestamp.ts} +3 -3
  173. package/src/dates/getTodayUTCTimestamp.ts +10 -0
  174. package/src/dates/{modifyDateBy.js → modifyDateBy.ts} +1 -1
  175. package/src/dates/transformDateToSecondaryType.ts +21 -0
  176. package/src/features/calendar/Buddhist.ts +1 -0
  177. package/src/features/calendar/Gregorian.ts +1 -0
  178. package/src/features/calendar/Islamic.ts +1 -0
  179. package/src/features/calendar/Japanese.ts +1 -0
  180. package/src/features/calendar/Persian.ts +1 -0
  181. package/src/getCachedLocaleDataInstance.ts +15 -0
  182. package/src/locale/{getLocaleData.js → getLocaleData.ts} +9 -8
  183. package/src/sap/base/util/{LoaderExtensions.js → LoaderExtensions.ts} +1 -1
  184. package/src/sap/ui/core/{Core.js → Configuration.ts} +5 -21
  185. package/src/sap/ui/core/Core.ts +15 -0
  186. package/src/sap/ui/core/FormatSettings.ts +16 -0
  187. package/tsconfig.json +13 -0
  188. package/used-modules.txt +4 -1
  189. package/hash.txt +0 -1
  190. package/src/DateFormat.js +0 -3
  191. package/src/LocaleData.js +0 -3
  192. package/src/dates/getTodayUTCTimestamp.js +0 -9
  193. package/src/getCachedLocaleDataInstance.js +0 -13
  194. /package/{src/features/calendar/Buddhist.js → dist/features/calendar/Buddhist.d.ts} +0 -0
  195. /package/{src/features/calendar/Gregorian.js → dist/features/calendar/Gregorian.d.ts} +0 -0
  196. /package/{src/features/calendar/Islamic.js → dist/features/calendar/Islamic.d.ts} +0 -0
  197. /package/{src/features/calendar/Japanese.js → dist/features/calendar/Japanese.d.ts} +0 -0
  198. /package/{src/features/calendar/Persian.js → dist/features/calendar/Persian.d.ts} +0 -0
  199. /package/src/{Assets-static.js → Assets-static.ts} +0 -0
  200. /package/src/{Assets.js → Assets.ts} +0 -0
@@ -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,42 +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](?:\.)?[\x20\xA0]?[mM](?:\.)?/;
944
- var aMatch = sValue.match(rAMPM);
945
- var bVariant = aMatch && aMatch.index === 0;
946
- if (bVariant) {
947
- sValue = aMatch[0];
948
- sAM = sAM.replace(/[\x20\xA0]/g, '');
949
- sPM = sPM.replace(/[\x20\xA0]/g, '');
950
- sValue = sValue.replace(/[\x20\xA0]/g, '');
951
- sAM = sAM.replace(/\./g, '').toLowerCase();
952
- sPM = sPM.replace(/\./g, '').toLowerCase();
953
- sValue = sValue.replace(/\./g, '').toLowerCase();
954
- }
955
- if (sValue.indexOf(sAM) === 0) {
956
- bPM = false;
957
- iLength = bVariant ? aMatch[0].length : sAM.length;
958
- } else if (sValue.indexOf(sPM) === 0) {
959
- bPM = true;
960
- 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
+ }
961
1134
  }
962
- return {
963
- pm: bPM,
964
- length: iLength
965
- };
1135
+ return { valid: false };
966
1136
  }
967
1137
  },
968
1138
  'H': {
969
1139
  name: 'hour0_23',
970
- format: function (oField, oDate, bUTC, oFormat) {
971
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1140
+ format: function (oField, oDate) {
1141
+ var iHours = oDate.getUTCHours();
972
1142
  return String(iHours).padStart(oField.digits, '0');
973
1143
  },
974
1144
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -988,8 +1158,8 @@ DateFormat.prototype.oSymbols = {
988
1158
  },
989
1159
  'k': {
990
1160
  name: 'hour1_24',
991
- format: function (oField, oDate, bUTC, oFormat) {
992
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1161
+ format: function (oField, oDate) {
1162
+ var iHours = oDate.getUTCHours();
993
1163
  var sHours = iHours === 0 ? '24' : String(iHours);
994
1164
  return sHours.padStart(oField.digits, '0');
995
1165
  },
@@ -1013,8 +1183,8 @@ DateFormat.prototype.oSymbols = {
1013
1183
  },
1014
1184
  'K': {
1015
1185
  name: 'hour0_11',
1016
- format: function (oField, oDate, bUTC, oFormat) {
1017
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1186
+ format: function (oField, oDate) {
1187
+ var iHours = oDate.getUTCHours();
1018
1188
  var sHours = String(iHours > 11 ? iHours - 12 : iHours);
1019
1189
  return sHours.padStart(oField.digits, '0');
1020
1190
  },
@@ -1035,8 +1205,8 @@ DateFormat.prototype.oSymbols = {
1035
1205
  },
1036
1206
  'h': {
1037
1207
  name: 'hour1_12',
1038
- format: function (oField, oDate, bUTC, oFormat) {
1039
- var iHours = bUTC ? oDate.getUTCHours() : oDate.getHours();
1208
+ format: function (oField, oDate) {
1209
+ var iHours = oDate.getUTCHours();
1040
1210
  var sHours;
1041
1211
  if (iHours > 12) {
1042
1212
  sHours = String(iHours - 12);
@@ -1069,8 +1239,8 @@ DateFormat.prototype.oSymbols = {
1069
1239
  },
1070
1240
  'm': {
1071
1241
  name: 'minute',
1072
- format: function (oField, oDate, bUTC, oFormat) {
1073
- var iMinutes = bUTC ? oDate.getUTCMinutes() : oDate.getMinutes();
1242
+ format: function (oField, oDate) {
1243
+ var iMinutes = oDate.getUTCMinutes();
1074
1244
  return String(iMinutes).padStart(oField.digits, '0');
1075
1245
  },
1076
1246
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -1090,8 +1260,8 @@ DateFormat.prototype.oSymbols = {
1090
1260
  },
1091
1261
  's': {
1092
1262
  name: 'second',
1093
- format: function (oField, oDate, bUTC, oFormat) {
1094
- var iSeconds = bUTC ? oDate.getUTCSeconds() : oDate.getSeconds();
1263
+ format: function (oField, oDate) {
1264
+ var iSeconds = oDate.getUTCSeconds();
1095
1265
  return String(iSeconds).padStart(oField.digits, '0');
1096
1266
  },
1097
1267
  parse: function (sValue, oPart, oFormat, oConfig) {
@@ -1111,8 +1281,8 @@ DateFormat.prototype.oSymbols = {
1111
1281
  },
1112
1282
  'S': {
1113
1283
  name: 'fractionalsecond',
1114
- format: function (oField, oDate, bUTC, oFormat) {
1115
- var iMilliseconds = bUTC ? oDate.getUTCMilliseconds() : oDate.getMilliseconds();
1284
+ format: function (oField, oDate) {
1285
+ var iMilliseconds = oDate.getUTCMilliseconds();
1116
1286
  var sMilliseconds = String(iMilliseconds);
1117
1287
  var sFractionalseconds = sMilliseconds.padStart(3, '0');
1118
1288
  sFractionalseconds = sFractionalseconds.substr(0, oField.digits);
@@ -1133,17 +1303,18 @@ DateFormat.prototype.oSymbols = {
1133
1303
  },
1134
1304
  'z': {
1135
1305
  name: 'timezoneGeneral',
1136
- format: function (oField, oDate, bUTC, oFormat) {
1306
+ format: function (oField, oDate, bUTC, oFormat, sTimezone) {
1137
1307
  if (oField.digits > 3 && oDate.getTimezoneLong && oDate.getTimezoneLong()) {
1138
1308
  return oDate.getTimezoneLong();
1139
1309
  } else if (oDate.getTimezoneShort && oDate.getTimezoneShort()) {
1140
1310
  return oDate.getTimezoneShort();
1141
1311
  }
1312
+ var iTimezoneOffset = TimezoneUtil.calculateOffset(oDate, sTimezone);
1142
1313
  var sTimeZone = 'GMT';
1143
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1144
- var bPositiveOffset = oDate.getTimezoneOffset() > 0;
1314
+ var iTZOffset = Math.abs(iTimezoneOffset / 60);
1315
+ var bPositiveOffset = iTimezoneOffset > 0;
1145
1316
  var iHourOffset = Math.floor(iTZOffset / 60);
1146
- var iMinuteOffset = iTZOffset % 60;
1317
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1147
1318
  if (!bUTC && iTZOffset != 0) {
1148
1319
  sTimeZone += bPositiveOffset ? '-' : '+';
1149
1320
  sTimeZone += String(iHourOffset).padStart(2, '0');
@@ -1181,11 +1352,12 @@ DateFormat.prototype.oSymbols = {
1181
1352
  },
1182
1353
  'Z': {
1183
1354
  name: 'timezoneRFC822',
1184
- format: function (oField, oDate, bUTC, oFormat) {
1185
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1186
- 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;
1187
1359
  var iHourOffset = Math.floor(iTZOffset / 60);
1188
- var iMinuteOffset = iTZOffset % 60;
1360
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1189
1361
  var sTimeZone = '';
1190
1362
  if (!bUTC) {
1191
1363
  sTimeZone += bPositiveOffset ? '-' : '+';
@@ -1200,11 +1372,12 @@ DateFormat.prototype.oSymbols = {
1200
1372
  },
1201
1373
  'X': {
1202
1374
  name: 'timezoneISO8601',
1203
- format: function (oField, oDate, bUTC, oFormat) {
1204
- var iTZOffset = Math.abs(oDate.getTimezoneOffset());
1205
- 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;
1206
1379
  var iHourOffset = Math.floor(iTZOffset / 60);
1207
- var iMinuteOffset = iTZOffset % 60;
1380
+ var iMinuteOffset = Math.floor(iTZOffset % 60);
1208
1381
  var sTimeZone = '';
1209
1382
  if (!bUTC && iTZOffset != 0) {
1210
1383
  sTimeZone += bPositiveOffset ? '-' : '+';
@@ -1230,11 +1403,52 @@ DateFormat.prototype.oSymbols = {
1230
1403
  return oParseHelper.parseTZ(sValue, oPart.digits === 3 || oPart.digits === 5);
1231
1404
  }
1232
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
+ }
1233
1447
  }
1234
1448
  };
1235
- DateFormat.prototype._format = function (oJSDate, bUTC) {
1449
+ DateFormat.prototype._format = function (oJSDate, bUTC, sTimezone) {
1236
1450
  if (this.oFormatOptions.relative) {
1237
- var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange);
1451
+ var sRes = this.formatRelative(oJSDate, bUTC, this.oFormatOptions.relativeRange, sTimezone);
1238
1452
  if (sRes) {
1239
1453
  return sRes;
1240
1454
  }
@@ -1245,10 +1459,10 @@ DateFormat.prototype._format = function (oJSDate, bUTC) {
1245
1459
  for (var i = 0; i < this.aFormatArray.length; i++) {
1246
1460
  oPart = this.aFormatArray[i];
1247
1461
  sSymbol = oPart.symbol || '';
1248
- aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this));
1462
+ aBuffer.push(this.oSymbols[sSymbol].format(oPart, oDate, bUTC, this, sTimezone));
1249
1463
  }
1250
1464
  sResult = aBuffer.join('');
1251
- if (Core.getConfiguration().getOriginInfo()) {
1465
+ if (Configuration.getOriginInfo()) {
1252
1466
  sResult = new String(sResult);
1253
1467
  sResult.originInfo = {
1254
1468
  source: 'Common Locale Data Repository',
@@ -1260,10 +1474,21 @@ DateFormat.prototype._format = function (oJSDate, bUTC) {
1260
1474
  return sResult;
1261
1475
  };
1262
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
+ }
1263
1487
  var sCalendarType = this.oFormatOptions.calendarType, sResult;
1264
1488
  if (bUTC === undefined) {
1265
1489
  bUTC = this.oFormatOptions.UTC;
1266
1490
  }
1491
+ sTimezone = sTimezone || Configuration.getTimezone();
1267
1492
  if (Array.isArray(vJSDate)) {
1268
1493
  if (!this.oFormatOptions.interval) {
1269
1494
  Log.error('Non-interval DateFormat can\'t format more than one date instance.');
@@ -1273,27 +1498,30 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1273
1498
  Log.error('Interval DateFormat can only format with 2 date instances but ' + vJSDate.length + ' is given.');
1274
1499
  return '';
1275
1500
  }
1501
+ vJSDate = vJSDate.map(function (oJSDate) {
1502
+ return convertToTimezone(oJSDate, sTimezone, bUTC);
1503
+ });
1276
1504
  if (this.oFormatOptions.singleIntervalValue) {
1277
1505
  if (vJSDate[0] === null) {
1278
1506
  Log.error('First date instance which is passed to the interval DateFormat shouldn\'t be null.');
1279
1507
  return '';
1280
1508
  }
1281
1509
  if (vJSDate[1] === null) {
1282
- sResult = this._format(vJSDate[0], bUTC);
1510
+ sResult = this._format(vJSDate[0], bUTC, sTimezone);
1283
1511
  }
1284
1512
  }
1285
1513
  if (sResult === undefined) {
1286
- var bValid = vJSDate.every(function (oJSDate) {
1287
- return oJSDate && !isNaN(oJSDate.getTime());
1288
- });
1289
- if (!bValid) {
1514
+ if (!vJSDate.every(isValidDateObject)) {
1290
1515
  Log.error('At least one date instance which is passed to the interval DateFormat isn\'t valid.');
1291
1516
  return '';
1292
1517
  }
1293
1518
  sResult = this._formatInterval(vJSDate, bUTC);
1294
1519
  }
1295
1520
  } else {
1296
- 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
+ }
1297
1525
  Log.error('The given date instance isn\'t valid.');
1298
1526
  return '';
1299
1527
  }
@@ -1301,7 +1529,8 @@ DateFormat.prototype.format = function (vJSDate, bUTC) {
1301
1529
  Log.error('Interval DateFormat expects an array with two dates for the first argument but only one date is given.');
1302
1530
  return '';
1303
1531
  }
1304
- sResult = this._format(vJSDate, bUTC);
1532
+ vJSDate = convertToTimezone(vJSDate, sTimezone, bUTC);
1533
+ sResult = this._format(vJSDate, bUTC, sTimezone);
1305
1534
  }
1306
1535
  if (sCalendarType == CalendarType.Japanese && this.oLocale.getLanguage() === 'ja') {
1307
1536
  sResult = sResult.replace(/(^|[^\d])1年/g, '$1元年');
@@ -1321,7 +1550,7 @@ DateFormat.prototype._formatInterval = function (aJSDates, bUTC) {
1321
1550
  var oDiffField = this._getGreatestDiffField([
1322
1551
  oFromDate,
1323
1552
  oToDate
1324
- ], bUTC);
1553
+ ]);
1325
1554
  if (!oDiffField) {
1326
1555
  return this._format(aJSDates[0], bUTC);
1327
1556
  }
@@ -1354,10 +1583,10 @@ var mFieldToGroup = {
1354
1583
  Minutes: 'Minute',
1355
1584
  Seconds: 'Second'
1356
1585
  };
1357
- DateFormat.prototype._getGreatestDiffField = function (aDates, bUTC) {
1586
+ DateFormat.prototype._getGreatestDiffField = function (aDates) {
1358
1587
  var bDiffFound = false, mDiff = {};
1359
1588
  this.aIntervalCompareFields.forEach(function (sField) {
1360
- 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]);
1361
1590
  if (!deepEqual(vFromValue, vToValue)) {
1362
1591
  bDiffFound = true;
1363
1592
  mDiff[sFieldGroup] = true;
@@ -1368,9 +1597,12 @@ DateFormat.prototype._getGreatestDiffField = function (aDates, bUTC) {
1368
1597
  }
1369
1598
  return null;
1370
1599
  };
1371
- DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1372
- var iIndex = 0, oPart, sSubValue, oResult;
1373
- 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
+ };
1374
1606
  var oParseConf = {
1375
1607
  formatArray: aFormatArray,
1376
1608
  dateValue: oDateValue,
@@ -1380,7 +1612,10 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1380
1612
  sSubValue = sValue.substr(iIndex);
1381
1613
  oPart = aFormatArray[i];
1382
1614
  oParseConf.index = i;
1383
- 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
+ }
1384
1619
  oDateValue = extend(oDateValue, oResult);
1385
1620
  if (oResult.valid === false) {
1386
1621
  break;
@@ -1388,7 +1623,12 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1388
1623
  iIndex += oResult.length || 0;
1389
1624
  }
1390
1625
  oDateValue.index = iIndex;
1391
- 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) {
1392
1632
  oDateValue.hour += 12;
1393
1633
  }
1394
1634
  if (oDateValue.dayNumberOfWeek === undefined && oDateValue.dayOfWeek !== undefined) {
@@ -1400,7 +1640,7 @@ DateFormat.prototype._parse = function (sValue, aFormatArray, bUTC, bStrict) {
1400
1640
  }
1401
1641
  return oDateValue;
1402
1642
  };
1403
- DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bStrict) {
1643
+ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bStrict, sTimezone) {
1404
1644
  var aDateValues, iRepeat, oDateValue;
1405
1645
  this.intervalPatterns.some(function (sPattern) {
1406
1646
  var aFormatArray = this.parseCldrDatePattern(sPattern);
@@ -1412,7 +1652,7 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1412
1652
  }
1413
1653
  }
1414
1654
  if (iRepeat === undefined) {
1415
- oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict);
1655
+ oDateValue = this._parse(sValue, aFormatArray, bUTC, bStrict, sTimezone);
1416
1656
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1417
1657
  oDateValue.valid = false;
1418
1658
  }
@@ -1426,13 +1666,13 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1426
1666
  return true;
1427
1667
  } else {
1428
1668
  aDateValues = [];
1429
- oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict);
1669
+ oDateValue = this._parse(sValue, aFormatArray.slice(0, iRepeat), bUTC, bStrict, sTimezone);
1430
1670
  if (oDateValue.valid === false) {
1431
1671
  return;
1432
1672
  }
1433
1673
  aDateValues.push(oDateValue);
1434
1674
  var iLength = oDateValue.index;
1435
- oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict);
1675
+ oDateValue = this._parse(sValue.substring(iLength), aFormatArray.slice(iRepeat), bUTC, bStrict, sTimezone);
1436
1676
  if (oDateValue.index === 0 || oDateValue.index + iLength < sValue.length) {
1437
1677
  oDateValue.valid = false;
1438
1678
  }
@@ -1445,65 +1685,62 @@ DateFormat.prototype._parseInterval = function (sValue, sCalendarType, bUTC, bSt
1445
1685
  }.bind(this));
1446
1686
  return aDateValues;
1447
1687
  };
1448
- 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
+ }
1449
1709
  var oDate, iYear = typeof oDateValue.year === 'number' ? oDateValue.year : 1970;
1450
- if (oDateValue.valid) {
1451
- if (bUTC || oDateValue.tzDiff !== undefined) {
1452
- oDate = UniversalDate.getInstance(new Date(0), sCalendarType);
1453
- oDate.setUTCEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1454
- oDate.setUTCFullYear(iYear);
1455
- oDate.setUTCMonth(oDateValue.month || 0);
1456
- oDate.setUTCDate(oDateValue.day || 1);
1457
- oDate.setUTCHours(oDateValue.hour || 0);
1458
- oDate.setUTCMinutes(oDateValue.minute || 0);
1459
- oDate.setUTCSeconds(oDateValue.second || 0);
1460
- oDate.setUTCMilliseconds(oDateValue.millisecond || 0);
1461
- if (bStrict && (oDateValue.day || 1) !== oDate.getUTCDate()) {
1462
- oDateValue.valid = false;
1463
- oDate = undefined;
1464
- } else {
1465
- if (oDateValue.tzDiff) {
1466
- oDate.setUTCMinutes((oDateValue.minute || 0) + oDateValue.tzDiff);
1467
- }
1468
- if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1469
- oDate.setUTCWeek({
1470
- year: oDateValue.weekYear || oDateValue.year,
1471
- week: oDateValue.week
1472
- });
1473
- if (oDateValue.dayNumberOfWeek !== undefined) {
1474
- oDate.setUTCDate(oDate.getUTCDate() + oDateValue.dayNumberOfWeek - 1);
1475
- }
1476
- }
1477
- }
1478
- } else {
1479
- oDate = UniversalDate.getInstance(new Date(1970, 0, 1, 0, 0, 0), sCalendarType);
1480
- oDate.setEra(oDateValue.era || UniversalDate.getCurrentEra(sCalendarType));
1481
- oDate.setFullYear(iYear);
1482
- oDate.setMonth(oDateValue.month || 0);
1483
- oDate.setDate(oDateValue.day || 1);
1484
- oDate.setHours(oDateValue.hour || 0);
1485
- oDate.setMinutes(oDateValue.minute || 0);
1486
- oDate.setSeconds(oDateValue.second || 0);
1487
- oDate.setMilliseconds(oDateValue.millisecond || 0);
1488
- if (bStrict && (oDateValue.day || 1) !== oDate.getDate()) {
1489
- oDateValue.valid = false;
1490
- oDate = undefined;
1491
- } else if (oDateValue.week !== undefined && (oDateValue.month === undefined || oDateValue.day === undefined)) {
1492
- oDate.setWeek({
1493
- year: oDateValue.weekYear || oDateValue.year,
1494
- week: oDateValue.week
1495
- });
1496
- if (oDateValue.dayNumberOfWeek !== undefined) {
1497
- oDate.setDate(oDate.getDate() + oDateValue.dayNumberOfWeek - 1);
1498
- }
1499
- }
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;
1500
1735
  }
1501
- if (oDateValue.valid) {
1502
- oDate = oDate.getJSDate();
1503
- return oDate;
1736
+ if (sTimezone) {
1737
+ oDateValue.tzDiff = TimezoneUtil.calculateOffset(oDate, sTimezone);
1504
1738
  }
1505
1739
  }
1506
- return null;
1740
+ if (oDateValue.tzDiff) {
1741
+ oDate.setUTCSeconds(oDate.getUTCSeconds() + oDateValue.tzDiff);
1742
+ }
1743
+ return oDate;
1507
1744
  };
1508
1745
  function mergeWithoutOverwrite(object1, object2) {
1509
1746
  if (object1 === object2) {
@@ -1526,13 +1763,33 @@ function isValidDateRange(oStartDate, oEndDate) {
1526
1763
  }
1527
1764
  return true;
1528
1765
  }
1766
+ function isValidDateObject(oDate) {
1767
+ return oDate && typeof oDate.getTime === 'function' && !isNaN(oDate.getTime());
1768
+ }
1529
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
+ }
1530
1789
  sValue = sValue == null ? '' : String(sValue).trim();
1531
1790
  var oDateValue;
1532
1791
  var sCalendarType = this.oFormatOptions.calendarType;
1533
- if (bUTC === undefined) {
1534
- bUTC = this.oFormatOptions.UTC;
1535
- }
1792
+ sTimezone = sTimezone || Configuration.getTimezone();
1536
1793
  if (bStrict === undefined) {
1537
1794
  bStrict = this.oFormatOptions.strictParsing;
1538
1795
  }
@@ -1544,22 +1801,40 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1544
1801
  if (oJSDate) {
1545
1802
  return oJSDate;
1546
1803
  }
1547
- oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict);
1804
+ oDateValue = this._parse(sValue, this.aFormatArray, bUTC, bStrict, sTimezone);
1548
1805
  if (oDateValue.index === 0 || oDateValue.index < sValue.length) {
1549
1806
  oDateValue.valid = false;
1550
1807
  }
1551
- oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict);
1808
+ oJSDate = fnCreateDate(oDateValue, sCalendarType, bUTC, bStrict, sTimezone, this.oFormatOptions, this.oLocale);
1552
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
+ }
1553
1828
  return oJSDate;
1554
1829
  }
1555
1830
  } else {
1556
- var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict);
1831
+ var aDateValues = this._parseInterval(sValue, sCalendarType, bUTC, bStrict, sTimezone);
1557
1832
  var oJSDate1, oJSDate2;
1558
1833
  if (aDateValues && aDateValues.length == 2) {
1559
1834
  var oDateValue1 = mergeWithoutOverwrite(aDateValues[0], aDateValues[1]);
1560
1835
  var oDateValue2 = mergeWithoutOverwrite(aDateValues[1], aDateValues[0]);
1561
- oJSDate1 = fnCreateDate(oDateValue1, sCalendarType, bUTC, bStrict);
1562
- 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);
1563
1838
  if (oJSDate1 && oJSDate2) {
1564
1839
  if (this.oFormatOptions.singleIntervalValue && oJSDate1.getTime() === oJSDate2.getTime()) {
1565
1840
  return [
@@ -1585,8 +1860,11 @@ DateFormat.prototype.parse = function (sValue, bUTC, bStrict) {
1585
1860
  if (!this.bIsFallback) {
1586
1861
  var vDate;
1587
1862
  this.aFallbackFormats.every(function (oFallbackFormat) {
1588
- vDate = oFallbackFormat.parse(sValue, bUTC, bStrict);
1863
+ vDate = oFallbackFormat.parse(sValue, bUTCInputParameter, bStrict);
1589
1864
  if (Array.isArray(vDate)) {
1865
+ if (oFallbackFormat.type === mDateFormatTypes.DATETIME_WITH_TIMEZONE) {
1866
+ return false;
1867
+ }
1590
1868
  return !(vDate[0] && vDate[1]);
1591
1869
  } else {
1592
1870
  return !vDate;
@@ -1735,23 +2013,20 @@ DateFormat.prototype.parseRelative = function (sValue, bUTC) {
1735
2013
  }
1736
2014
  }
1737
2015
  };
1738
- DateFormat.prototype.formatRelative = function (oJSDate, bUTC, aRange) {
1739
- 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;
1740
2018
  iDiffSeconds = (oJSDate.getTime() - oToday.getTime()) / 1000;
1741
2019
  if (this.oFormatOptions.relativeScale == 'auto') {
1742
2020
  sScale = this._getScale(iDiffSeconds, this.aRelativeScales);
2021
+ sScale = fixScaleForMonths(oJSDate, oToday, sScale, iDiffSeconds);
1743
2022
  }
1744
2023
  if (!aRange) {
1745
2024
  aRange = this._mRanges[sScale];
1746
2025
  }
1747
2026
  if (sScale == 'year' || sScale == 'month' || sScale == 'day') {
1748
- oToday = new Date(Date.UTC(oToday.getFullYear(), oToday.getMonth(), oToday.getDate()));
2027
+ oToday = new Date(Date.UTC(oToday.getUTCFullYear(), oToday.getUTCMonth(), oToday.getUTCDate()));
1749
2028
  oDateUTC = new Date(0);
1750
- if (bUTC) {
1751
- oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
1752
- } else {
1753
- oDateUTC.setUTCFullYear(oJSDate.getFullYear(), oJSDate.getMonth(), oJSDate.getDate());
1754
- }
2029
+ oDateUTC.setUTCFullYear(oJSDate.getUTCFullYear(), oJSDate.getUTCMonth(), oJSDate.getUTCDate());
1755
2030
  oJSDate = oDateUTC;
1756
2031
  }
1757
2032
  iDiff = this._getDifference(sScale, [
@@ -1819,6 +2094,21 @@ DateFormat.prototype._getScale = function (iDiffSeconds, aScales) {
1819
2094
  }
1820
2095
  return sScale;
1821
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
+ }
1822
2112
  function cutDateFields(oDate, iStartIndex) {
1823
2113
  var aFields = [
1824
2114
  'FullYear',
@@ -1831,21 +2121,21 @@ function cutDateFields(oDate, iStartIndex) {
1831
2121
  ], sMethodName;
1832
2122
  var oDateCopy = new Date(oDate.getTime());
1833
2123
  for (var i = iStartIndex; i < aFields.length; i++) {
1834
- sMethodName = 'set' + aFields[iStartIndex];
2124
+ sMethodName = 'setUTC' + aFields[iStartIndex];
1835
2125
  oDateCopy[sMethodName].apply(oDateCopy, [0]);
1836
2126
  }
1837
2127
  return oDateCopy;
1838
2128
  }
1839
2129
  var mRelativeDiffs = {
1840
2130
  year: function (oFromDate, oToDate) {
1841
- return oToDate.getFullYear() - oFromDate.getFullYear();
2131
+ return oToDate.getUTCFullYear() - oFromDate.getUTCFullYear();
1842
2132
  },
1843
2133
  month: function (oFromDate, oToDate) {
1844
- return oToDate.getMonth() - oFromDate.getMonth() + this.year(oFromDate, oToDate) * 12;
2134
+ return oToDate.getUTCMonth() - oFromDate.getUTCMonth() + this.year(oFromDate, oToDate) * 12;
1845
2135
  },
1846
2136
  week: function (oFromDate, oToDate, oFormat) {
1847
- var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getDay());
1848
- var iToDay = oFormat._adaptDayOfWeek(oToDate.getDay());
2137
+ var iFromDay = oFormat._adaptDayOfWeek(oFromDate.getUTCDay());
2138
+ var iToDay = oFormat._adaptDayOfWeek(oToDate.getUTCDay());
1849
2139
  oFromDate = cutDateFields(oFromDate, 3);
1850
2140
  oToDate = cutDateFields(oToDate, 3);
1851
2141
  return (oToDate.getTime() - oFromDate.getTime() - (iToDay - iFromDay) * oFormat._mScales.day * 1000) / (oFormat._mScales.week * 1000);
@@ -1872,7 +2162,12 @@ var mRelativeDiffs = {
1872
2162
  }
1873
2163
  };
1874
2164
  DateFormat.prototype._adaptDayOfWeek = function (iDayOfWeek) {
1875
- 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
+ }
1876
2171
  var iDayNumberOfWeek = iDayOfWeek - (iFirstDayOfWeek - 1);
1877
2172
  if (iDayNumberOfWeek <= 0) {
1878
2173
  iDayNumberOfWeek += 7;