@beinformed/ui 1.58.3 → 1.59.0

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 (74) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/esm/constants/Constants.js +10 -0
  3. package/esm/constants/Constants.js.map +1 -1
  4. package/esm/constants/Settings.js +5 -1
  5. package/esm/constants/Settings.js.map +1 -1
  6. package/esm/models/attributes/DatetimeAttributeModel.js +39 -4
  7. package/esm/models/attributes/DatetimeAttributeModel.js.map +1 -1
  8. package/esm/models/attributes/input-constraints/DatetimeFormatConstraint.js +31 -2
  9. package/esm/models/attributes/input-constraints/DatetimeFormatConstraint.js.map +1 -1
  10. package/esm/models/content/SectionModel.js +1 -1
  11. package/esm/models/content/SectionModel.js.map +1 -1
  12. package/esm/models/content/SubSectionModel.js +12 -4
  13. package/esm/models/content/SubSectionModel.js.map +1 -1
  14. package/esm/react-client/client.js +2 -1
  15. package/esm/react-client/client.js.map +1 -1
  16. package/esm/react-server/serverUtil.js +2 -1
  17. package/esm/react-server/serverUtil.js.map +1 -1
  18. package/esm/redux/actions/Preferences.js +15 -1
  19. package/esm/redux/actions/Preferences.js.map +1 -1
  20. package/esm/utils/datetime/DateTimeUtil.js +292 -94
  21. package/esm/utils/datetime/DateTimeUtil.js.map +1 -1
  22. package/lib/constants/Constants.js +11 -1
  23. package/lib/constants/Constants.js.flow +11 -0
  24. package/lib/constants/Constants.js.map +1 -1
  25. package/lib/constants/Settings.js +7 -2
  26. package/lib/constants/Settings.js.flow +6 -0
  27. package/lib/constants/Settings.js.map +1 -1
  28. package/lib/models/attributes/DatetimeAttributeModel.js +38 -3
  29. package/lib/models/attributes/DatetimeAttributeModel.js.flow +54 -4
  30. package/lib/models/attributes/DatetimeAttributeModel.js.map +1 -1
  31. package/lib/models/attributes/__tests__/DatetimeAttributeModel.spec.js.flow +9 -0
  32. package/lib/models/attributes/__tests__/DatetimeAttributeModel_offset.spec.js.flow +306 -0
  33. package/lib/models/attributes/input-constraints/DatetimeFormatConstraint.js +31 -2
  34. package/lib/models/attributes/input-constraints/DatetimeFormatConstraint.js.flow +42 -3
  35. package/lib/models/attributes/input-constraints/DatetimeFormatConstraint.js.map +1 -1
  36. package/lib/models/content/SectionModel.js +1 -1
  37. package/lib/models/content/SectionModel.js.flow +2 -1
  38. package/lib/models/content/SectionModel.js.map +1 -1
  39. package/lib/models/content/SubSectionModel.js +12 -3
  40. package/lib/models/content/SubSectionModel.js.flow +20 -3
  41. package/lib/models/content/SubSectionModel.js.map +1 -1
  42. package/lib/models/content/__tests__/ContentModel.spec.js.flow +3 -3
  43. package/lib/react-client/client.js +1 -0
  44. package/lib/react-client/client.js.flow +2 -0
  45. package/lib/react-client/client.js.map +1 -1
  46. package/lib/react-server/__tests__/serverUtil.spec.js.flow +12 -0
  47. package/lib/react-server/serverUtil.js +1 -0
  48. package/lib/react-server/serverUtil.js.flow +2 -0
  49. package/lib/react-server/serverUtil.js.map +1 -1
  50. package/lib/redux/actions/Preferences.js +17 -2
  51. package/lib/redux/actions/Preferences.js.flow +22 -0
  52. package/lib/redux/actions/Preferences.js.map +1 -1
  53. package/lib/redux/reducers/__tests__/ModelCatalogReducer.spec.js.flow +23 -0
  54. package/lib/utils/datetime/DateTimeUtil.js +292 -93
  55. package/lib/utils/datetime/DateTimeUtil.js.flow +482 -172
  56. package/lib/utils/datetime/DateTimeUtil.js.map +1 -1
  57. package/lib/utils/datetime/__tests__/DateTime.spec.js.flow +771 -483
  58. package/package.json +11 -9
  59. package/src/constants/Constants.js +11 -0
  60. package/src/constants/Settings.js +6 -0
  61. package/src/models/attributes/DatetimeAttributeModel.js +54 -4
  62. package/src/models/attributes/__tests__/DatetimeAttributeModel.spec.js +9 -0
  63. package/src/models/attributes/__tests__/DatetimeAttributeModel_offset.spec.js +306 -0
  64. package/src/models/attributes/input-constraints/DatetimeFormatConstraint.js +42 -3
  65. package/src/models/content/SectionModel.js +2 -1
  66. package/src/models/content/SubSectionModel.js +20 -3
  67. package/src/models/content/__tests__/ContentModel.spec.js +3 -3
  68. package/src/react-client/client.js +2 -0
  69. package/src/react-server/__tests__/serverUtil.spec.js +12 -0
  70. package/src/react-server/serverUtil.js +2 -0
  71. package/src/redux/actions/Preferences.js +22 -0
  72. package/src/redux/reducers/__tests__/ModelCatalogReducer.spec.js +23 -0
  73. package/src/utils/datetime/DateTimeUtil.js +482 -172
  74. package/src/utils/datetime/__tests__/DateTime.spec.js +771 -483
@@ -5,53 +5,81 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.TimestampUtil = exports.TimeUtil = exports.DateUtil = exports.DateTimeUtil = void 0;
8
+ var _startsWith = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/starts-with"));
9
+ var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
10
+ var _trunc = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/math/trunc"));
11
+ var _padStart = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/pad-start"));
8
12
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
9
13
  var _dateFns = require("date-fns");
10
14
  var _locale = require("date-fns/locale");
11
- var _Cookies = require("../browser/Cookies");
12
- var _Settings = require("../../constants/Settings");
15
+ var _tz = require("@date-fns/tz");
16
+ var _timezoneSoft = _interopRequireDefault(require("timezone-soft"));
13
17
  var _constants = require("../../constants");
18
+ var _Cookies = require("../browser/Cookies");
14
19
  /**
15
20
  * @hideconstructor
16
21
  */
17
22
  class BaseDateTimeUtil {
18
23
  constructor(isoFormat) {
19
24
  (0, _defineProperty2.default)(this, "_isoFormat", void 0);
25
+ (0, _defineProperty2.default)(this, "_timeZone", typeof Intl === "undefined" ? "Etc/UTC" : Intl.DateTimeFormat().resolvedOptions().timeZone || "Etc/UTC");
20
26
  this._isoFormat = isoFormat;
21
27
  }
22
28
 
23
29
  /**
30
+ * Returns the options defined in settings
24
31
  */
25
- getLocale() {
26
- const locale = (0, _Cookies.getCookie)("locale") ?? "en";
27
- if (locale === "nl") {
28
- return _locale.nl;
29
- }
30
- return _locale.enGB;
31
- }
32
-
33
- // returns the options defined in settings
34
32
  getOptions() {
35
33
  // indicates on what day the week starts
36
- const weekStartsOn = (0, _Settings.getSetting)("CALENDAR_WEEK_STARTS_ON", _constants.DEFAULT_WEEK_STARTS_ON);
34
+ const weekStartsOn = (0, _constants.getSetting)("CALENDAR_WEEK_STARTS_ON", _constants.DEFAULT_WEEK_STARTS_ON);
37
35
 
38
36
  // indicates which date indicates the first week of the year
39
- const firstWeekContainsDate = (0, _Settings.getSetting)("CALENDAR_FIRST_WEEK_CONTAINS_DATE", _constants.DEFAULT_FIRST_WEEK_CONTAINS_DATE);
37
+ const firstWeekContainsDate = (0, _constants.getSetting)("CALENDAR_FIRST_WEEK_CONTAINS_DATE", _constants.DEFAULT_FIRST_WEEK_CONTAINS_DATE);
40
38
  return {
41
39
  weekStartsOn,
42
40
  firstWeekContainsDate
43
41
  };
44
42
  }
45
43
 
44
+ /**
45
+ */
46
+ getIsoFormat() {
47
+ var _context;
48
+ if ((0, _constants.isIncludeTimeOffsetInDateTimes)() && (0, _startsWith.default)(_context = this._isoFormat).call(_context, _constants.ISO_DATETIME_FORMAT)) {
49
+ return this._isoFormat + _constants.DATETIME_OFFSET_FORMAT;
50
+ }
51
+ return this._isoFormat;
52
+ }
53
+
54
+ /**
55
+ */
56
+ convertFormat(sourceFormat) {
57
+ return sourceFormat ? sourceFormat : this.getIsoFormat();
58
+ }
59
+
60
+ /**
61
+ */
62
+ getLocale() {
63
+ const locale = (0, _Cookies.getCookie)("locale") ?? "en";
64
+ if (locale === "nl") {
65
+ return _locale.nl;
66
+ }
67
+ return _locale.enGB;
68
+ }
69
+
46
70
  /**
47
71
  */
48
72
  toDate(date) {
49
- let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._isoFormat;
73
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
74
+ if (date instanceof Date) {
75
+ return date;
76
+ }
50
77
  const {
51
78
  weekStartsOn,
52
79
  firstWeekContainsDate
53
80
  } = this.getOptions();
54
81
  return (0, _dateFns.parse)(date, inputFormat, new Date(), {
82
+ in: this.getDateFnsContext(),
55
83
  weekStartsOn,
56
84
  firstWeekContainsDate
57
85
  });
@@ -59,13 +87,15 @@ class BaseDateTimeUtil {
59
87
 
60
88
  /**
61
89
  */
62
- toFormat(date, targetFormat) {
90
+ toFormat(isoDate, targetFormat) {
91
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
63
92
  const {
64
93
  weekStartsOn
65
94
  } = this.getOptions();
66
- const parsedDate = typeof date === "string" ? this.toDate(date) : date;
95
+ const parsedDate = this.toDate(isoDate, inputFormat);
67
96
  if ((0, _dateFns.isValid)(parsedDate)) {
68
97
  return (0, _dateFns.format)(parsedDate, targetFormat, {
98
+ in: this.getDateFnsContext(),
69
99
  weekStartsOn,
70
100
  locale: this.getLocale()
71
101
  });
@@ -76,17 +106,8 @@ class BaseDateTimeUtil {
76
106
  /**
77
107
  */
78
108
  toISO(date) {
79
- let sourceFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._isoFormat;
80
- const {
81
- weekStartsOn
82
- } = this.getOptions();
83
- const parsedDate = typeof date === "string" ? this.toDate(date, sourceFormat) : date;
84
- if ((0, _dateFns.isValid)(parsedDate)) {
85
- return (0, _dateFns.format)(parsedDate, this._isoFormat, {
86
- weekStartsOn
87
- });
88
- }
89
- return "Invalid Date";
109
+ let sourceFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
110
+ return this.toFormat(date, this.getIsoFormat(), sourceFormat);
90
111
  }
91
112
 
92
113
  /**
@@ -95,86 +116,79 @@ class BaseDateTimeUtil {
95
116
  return this.toISO(new Date());
96
117
  }
97
118
 
98
- /**
99
- */
100
- convertFormat(sourceFormat) {
101
- return sourceFormat ? sourceFormat : this._isoFormat;
102
- }
119
+ //////////// VALIDATION
103
120
 
104
121
  /**
105
- * VALIDATION
106
122
  */
107
123
  hasFormat(date, sourceFormat) {
108
- const {
109
- weekStartsOn
110
- } = this.getOptions();
111
- const realDate = this.toDate(date, sourceFormat);
112
- if ((0, _dateFns.isValid)(realDate)) {
113
- const formattedValue = (0, _dateFns.format)(realDate, sourceFormat, {
114
- weekStartsOn
115
- });
116
- const isOutsideRange = (0, _dateFns.isBefore)(realDate, new Date(1000, 1, 1)) || (0, _dateFns.isAfter)(realDate, new Date(9999, 11, 31));
117
- if (isOutsideRange) {
118
- return false;
119
- }
120
- return formattedValue.replace(/0/gu, "").toUpperCase() === date.replace(/0/gu, "").toUpperCase();
124
+ const formattedValue = this.toFormat(date, sourceFormat, sourceFormat);
125
+ if (formattedValue === "Invalid Date") {
126
+ return false;
127
+ }
128
+ const isOutsideRange = (0, _dateFns.isBefore)(formattedValue, new Date(1000, 1, 1)) || (0, _dateFns.isAfter)(formattedValue, new Date(9999, 11, 31));
129
+ if (isOutsideRange) {
130
+ return false;
121
131
  }
122
- return false;
132
+ return formattedValue.replace(/0/gu, "").toUpperCase() === date.replace(/0/gu, "").toUpperCase();
123
133
  }
124
134
 
125
135
  /**
126
136
  */
127
137
  isValid(date) {
128
- let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._isoFormat;
129
- return (0, _dateFns.isValid)(this.toDate(date, inputFormat));
138
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
139
+ if (!date) {
140
+ return false;
141
+ }
142
+ const parsedDate = this.toDate(date, inputFormat);
143
+ return (0, _dateFns.isValid)(parsedDate);
130
144
  }
131
145
 
132
146
  /**
133
147
  */
134
148
  isAfter(inputDate, afterISODate) {
135
- let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._isoFormat;
149
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
136
150
  return afterISODate != null && (0, _dateFns.isAfter)(this.toDate(inputDate, inputFormat), this.toDate(afterISODate));
137
151
  }
138
152
 
139
153
  /**
140
154
  */
141
155
  isSameOrAfter(inputDate, afterISODate) {
142
- let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._isoFormat;
156
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
143
157
  return afterISODate != null && (this.isAfter(inputDate, afterISODate, inputFormat) || this.isSame(inputDate, afterISODate, inputFormat));
144
158
  }
145
159
 
146
160
  /**
147
161
  */
148
162
  isBefore(inputDate, beforeISODate) {
149
- let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._isoFormat;
163
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
150
164
  return beforeISODate != null && (0, _dateFns.isBefore)(this.toDate(inputDate, inputFormat), this.toDate(beforeISODate));
151
165
  }
152
166
 
153
167
  /**
154
168
  */
155
169
  isSameOrBefore(inputDate, beforeISODate) {
156
- let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._isoFormat;
170
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
157
171
  return beforeISODate != null && (this.isBefore(inputDate, beforeISODate, inputFormat) || this.isSame(inputDate, beforeISODate, inputFormat));
158
172
  }
159
173
 
160
174
  /**
161
175
  */
162
176
  isSame(inputDate, compareDate) {
163
- let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._isoFormat;
177
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
164
178
  return compareDate != null && this.toDate(inputDate, inputFormat).getTime() === this.toDate(compareDate).getTime();
165
179
  }
166
180
 
167
181
  /**
168
182
  */
169
183
  isSameDay(inputDate, compareDate) {
170
- let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._isoFormat;
184
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
171
185
  return compareDate != null && (0, _dateFns.isSameDay)(this.toDate(inputDate, inputFormat), this.toDate(compareDate, inputFormat));
172
186
  }
173
187
 
174
188
  /**
175
189
  */
176
190
  isOther(inputDate, compareDate) {
177
- let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this._isoFormat;
191
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
178
192
  return !this.isSame(inputDate, compareDate, inputFormat);
179
193
  }
180
194
 
@@ -188,191 +202,376 @@ class BaseDateTimeUtil {
188
202
  }
189
203
 
190
204
  /**
191
- * CALCULATIONS
205
+ * Checks if a given local date and time is ambiguous in the specified timezone.
206
+ * Ambiguity happens during the end of daylight saving time (DST) transitions.
207
+ */
208
+ isAmbiguous(inputDate) {
209
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
210
+ if (inputDate == null || typeof Intl === "undefined") {
211
+ return false;
212
+ }
213
+ const dateTime = this.toDate(inputDate, inputFormat);
214
+ if (!(0, _dateFns.isValid)(dateTime)) {
215
+ return false;
216
+ }
217
+ const t = [60, -60, 30, -30];
218
+ const a = (0, _map.default)(t).call(t, x => {
219
+ const newDate = (0, _dateFns.add)(dateTime, {
220
+ minutes: x
221
+ });
222
+ return (0, _dateFns.format)(newDate, "HH:mm");
223
+ });
224
+ const time = (0, _dateFns.format)(dateTime, "HH:mm");
225
+ return a.indexOf(time) > -1;
226
+ }
227
+
228
+ //////////// CALCULATIONS
229
+
230
+ /**
231
+ * @private
232
+ */
233
+ _calculate(date, calculationFn, property, value) {
234
+ let inputFormat = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : this.getIsoFormat();
235
+ const parsedDate = this.toDate(date, inputFormat);
236
+ return this.toISO(calculationFn(parsedDate, {
237
+ [property]: value
238
+ }, {
239
+ in: this.getDateFnsContext()
240
+ }));
241
+ }
242
+
243
+ /**
192
244
  */
193
245
  addSeconds(date, amount) {
194
- return this.toISO((0, _dateFns.addSeconds)(this.toDate(date), amount));
246
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
247
+ return this._calculate(date, _dateFns.add, "seconds", amount, inputFormat);
195
248
  }
196
249
 
197
250
  /**
198
251
  */
199
252
  addMinutes(date, amount) {
200
- return this.toISO((0, _dateFns.addMinutes)(this.toDate(date), amount));
253
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
254
+ return this._calculate(date, _dateFns.add, "minutes", amount, inputFormat);
201
255
  }
202
256
 
203
257
  /**
204
258
  */
205
259
  addHours(date, amount) {
206
- return this.toISO((0, _dateFns.addHours)(this.toDate(date), amount));
260
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
261
+ return this._calculate(date, _dateFns.add, "hours", amount, inputFormat);
207
262
  }
208
263
 
209
264
  /**
210
265
  */
211
266
  addDays(date, amount) {
212
- return this.toISO((0, _dateFns.addDays)(this.toDate(date), amount));
267
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
268
+ return this._calculate(date, _dateFns.add, "days", amount, inputFormat);
213
269
  }
214
270
 
215
271
  /**
216
272
  */
217
273
  addWeeks(date, amount) {
218
- return this.toISO((0, _dateFns.addWeeks)(this.toDate(date), amount));
274
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
275
+ return this._calculate(date, _dateFns.add, "weeks", amount, inputFormat);
219
276
  }
220
277
 
221
278
  /**
222
279
  */
223
280
  addMonths(date, amount) {
224
- return this.toISO((0, _dateFns.addMonths)(this.toDate(date), amount));
281
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
282
+ return this._calculate(date, _dateFns.add, "months", amount, inputFormat);
225
283
  }
226
284
 
227
285
  /**
228
286
  */
229
287
  addYears(date, amount) {
230
- return this.toISO((0, _dateFns.addYears)(this.toDate(date), amount));
288
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
289
+ return this._calculate(date, _dateFns.add, "years", amount, inputFormat);
231
290
  }
232
291
 
233
292
  /**
234
293
  */
235
294
  subtractSeconds(date, amount) {
236
- return this.toISO((0, _dateFns.subSeconds)(this.toDate(date), amount));
295
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
296
+ return this._calculate(date, _dateFns.sub, "seconds", amount, inputFormat);
237
297
  }
238
298
 
239
299
  /**
240
300
  */
241
301
  subtractMinutes(date, amount) {
242
- return this.toISO((0, _dateFns.subMinutes)(this.toDate(date), amount));
302
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
303
+ return this._calculate(date, _dateFns.sub, "minutes", amount, inputFormat);
243
304
  }
244
305
 
245
306
  /**
246
307
  */
247
308
  subtractHours(date, amount) {
248
- return this.toISO((0, _dateFns.subHours)(this.toDate(date), amount));
309
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
310
+ return this._calculate(date, _dateFns.sub, "hours", amount, inputFormat);
249
311
  }
250
312
 
251
313
  /**
252
314
  */
253
315
  subtractDays(date, amount) {
254
- return this.toISO((0, _dateFns.subDays)(this.toDate(date), amount));
316
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
317
+ return this._calculate(date, _dateFns.sub, "days", amount, inputFormat);
255
318
  }
256
319
 
257
320
  /**
258
321
  */
259
322
  subtractWeeks(date, amount) {
260
- return this.toISO((0, _dateFns.subWeeks)(this.toDate(date), amount));
323
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
324
+ return this._calculate(date, _dateFns.sub, "weeks", amount, inputFormat);
261
325
  }
262
326
 
263
327
  /**
264
328
  */
265
329
  subtractMonths(date, amount) {
266
- return this.toISO((0, _dateFns.subMonths)(this.toDate(date), amount));
330
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
331
+ return this._calculate(date, _dateFns.sub, "months", amount, inputFormat);
267
332
  }
268
333
 
269
334
  /**
270
335
  */
271
336
  subtractYears(date, amount) {
272
- return this.toISO((0, _dateFns.subYears)(this.toDate(date), amount));
337
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
338
+ return this._calculate(date, _dateFns.sub, "years", amount, inputFormat);
339
+ }
340
+
341
+ //////////// GETTERS
342
+
343
+ /**
344
+ * @private
345
+ */
346
+ _get(date, method) {
347
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
348
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
349
+ const parsedDate = this.toDate(date, inputFormat);
350
+ return this.toISO(method(parsedDate, {
351
+ in: this.getDateFnsContext(),
352
+ ...options
353
+ }));
273
354
  }
274
355
 
275
356
  /**
276
- * GETTERS
277
357
  */
278
358
  startOfMonth(date) {
279
- let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._isoFormat;
280
- return this.toISO((0, _dateFns.startOfMonth)(this.toDate(date, inputFormat)));
359
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
360
+ return this._get(date, _dateFns.startOfMonth, inputFormat);
281
361
  }
282
362
 
283
363
  /**
284
364
  */
285
365
  endOfMonth(date) {
286
- let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._isoFormat;
287
- return this.toISO((0, _dateFns.endOfMonth)(this.toDate(date, inputFormat)));
366
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
367
+ return this._get(date, _dateFns.endOfMonth, inputFormat);
288
368
  }
289
369
 
290
370
  /**
291
371
  */
292
372
  startOfWeek(date) {
293
- let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._isoFormat;
373
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
294
374
  const {
295
375
  weekStartsOn
296
376
  } = this.getOptions();
297
- return this.toISO((0, _dateFns.startOfWeek)(this.toDate(date, inputFormat), {
377
+ return this._get(date, _dateFns.startOfWeek, inputFormat, {
298
378
  weekStartsOn
299
- }));
379
+ });
300
380
  }
301
381
 
302
382
  /**
303
383
  */
304
384
  getHours(date) {
305
- const parsedDate = typeof date === "string" ? this.toDate(date) : date;
306
- return (0, _dateFns.getHours)(parsedDate);
385
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
386
+ const parsedDate = this.toDate(date, inputFormat);
387
+ return (0, _dateFns.getHours)(parsedDate, {
388
+ in: this.getDateFnsContext()
389
+ });
307
390
  }
308
391
 
309
392
  /**
310
393
  */
311
394
  getMinutes(date) {
312
- const parsedDate = typeof date === "string" ? this.toDate(date) : date;
313
- return (0, _dateFns.getMinutes)(parsedDate);
395
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
396
+ const parsedDate = this.toDate(date, inputFormat);
397
+ return (0, _dateFns.getMinutes)(parsedDate, {
398
+ in: this.getDateFnsContext()
399
+ });
314
400
  }
315
401
 
316
402
  /**
317
403
  */
318
404
  getWeek(date) {
405
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
319
406
  const {
320
407
  weekStartsOn,
321
408
  firstWeekContainsDate
322
409
  } = this.getOptions();
323
- return (0, _dateFns.getWeek)(this.toDate(date), {
410
+ const parsedDate = this.toDate(date, inputFormat);
411
+ return (0, _dateFns.getWeek)(parsedDate, {
412
+ in: this.getDateFnsContext(),
324
413
  weekStartsOn,
325
414
  firstWeekContainsDate
326
415
  });
327
416
  }
328
417
 
418
+ //////////// SETTERS
419
+
420
+ /**
421
+ * @private
422
+ */
423
+ _set(date, property, value) {
424
+ let inputFormat = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : this.getIsoFormat();
425
+ const parsedDate = this.toDate(date, inputFormat);
426
+ return this.toISO((0, _dateFns.set)(parsedDate, {
427
+ [property]: value
428
+ }
429
+ // {
430
+ // in: this.getDateFnsContext(),
431
+ // },
432
+ ));
433
+ }
434
+
329
435
  /**
330
- * SETTERS
331
436
  */
332
437
  setYear(date, year) {
333
- return this.toISO((0, _dateFns.setYear)(this.toDate(date), year));
438
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
439
+ return this._set(date, "year", year, inputFormat);
334
440
  }
335
441
 
336
442
  /**
337
443
  */
338
444
  setMonth(date, month) {
339
- return this.toISO((0, _dateFns.setMonth)(this.toDate(date), month));
445
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
446
+ return this._set(date, "month", month, inputFormat);
447
+ }
448
+
449
+ /**
450
+ */
451
+ setDay(date, day) {
452
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
453
+ return this._set(date, "date", day, inputFormat);
340
454
  }
341
455
 
342
456
  /**
343
457
  */
344
458
  setHour(date, hour) {
345
- return this.toISO((0, _dateFns.setHours)(this.toDate(date), hour));
459
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
460
+ return this._set(date, "hours", hour, inputFormat);
346
461
  }
347
462
 
348
463
  /**
349
464
  */
350
465
  setMinute(date, minute) {
351
- return this.toISO((0, _dateFns.setMinutes)(this.toDate(date), minute));
466
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
467
+ return this._set(date, "minutes", minute, inputFormat);
352
468
  }
353
469
 
354
470
  /**
355
471
  */
356
472
  setSecond(date, second) {
357
- return this.toISO((0, _dateFns.setSeconds)(this.toDate(date), second));
473
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
474
+ return this._set(date, "seconds", second, inputFormat);
358
475
  }
359
476
 
360
477
  /**
361
478
  */
362
- setMilliseconds(date, milliseconds) {
363
- return this.toISO((0, _dateFns.setMilliseconds)(this.toDate(date), milliseconds));
479
+ setMilliseconds(date, millisecond) {
480
+ let inputFormat = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.getIsoFormat();
481
+ return this._set(date, "milliseconds", millisecond, inputFormat);
364
482
  }
365
483
 
366
484
  /**
367
485
  */
368
486
  setTime(date, hours, minutes, seconds, milliseconds) {
369
- return this.toISO((0, _dateFns.set)(this.toDate(date), {
487
+ let inputFormat = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : this.getIsoFormat();
488
+ const parsedDate = this.toDate(date, inputFormat);
489
+ return this.toISO((0, _dateFns.set)(parsedDate, {
370
490
  hours,
371
491
  minutes,
372
492
  seconds,
373
493
  milliseconds
494
+ }, {
495
+ in: this.getDateFnsContext()
374
496
  }));
375
497
  }
498
+
499
+ //////////// Timezone related
500
+
501
+ /**
502
+ */
503
+ getTimeZone() {
504
+ return this._timeZone;
505
+ }
506
+
507
+ /**
508
+ */
509
+ setTimeZone(timeZone) {
510
+ this._timeZone = timeZone;
511
+ }
512
+
513
+ /**
514
+ */
515
+ getDateFnsContext() {
516
+ if (_constants.IS_GRAALJS) {
517
+ return null; // tz method does not work in graal (yet)
518
+ }
519
+ return (0, _tz.tz)(this.getTimeZone());
520
+ }
521
+
522
+ //////////// Offsets
523
+
524
+ /**
525
+ */
526
+ getOffset(date) {
527
+ let inputFormat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.getIsoFormat();
528
+ const parsedDate = this.toDate(date, inputFormat);
529
+ if ((0, _dateFns.isValid)(parsedDate)) {
530
+ const dateOffset = this.toFormat(parsedDate, _constants.DATETIME_OFFSET_FORMAT);
531
+ const offsets = this.getTimezoneOffsets();
532
+ if (typeof offsets.daylight !== "undefined" && offsets.daylight.value === dateOffset) {
533
+ return offsets.daylight;
534
+ } else if (typeof offsets.standard !== "undefined" && offsets.standard.value === dateOffset) {
535
+ return offsets.standard;
536
+ }
537
+ }
538
+ return null;
539
+ }
540
+
541
+ /**
542
+ */
543
+ getTimezoneOffsets() {
544
+ const createOffsetObject = info => {
545
+ var _context2, _context3;
546
+ const sign = info.offset < 0 ? "-" : "+";
547
+ const absOffset = Math.abs(info.offset);
548
+ const hours = (0, _trunc.default)(absOffset);
549
+ const minutes = Math.round(absOffset % 1 * 60);
550
+ const offsetString = `${sign}${(0, _padStart.default)(_context2 = String(hours + (minutes === 60 ? 1 : 0))).call(_context2, 2, "0")}:${(0, _padStart.default)(_context3 = String(minutes % 60)).call(_context3, 2, "0")}`;
551
+ return {
552
+ label: info.name,
553
+ abbr: info.abbr,
554
+ value: offsetString
555
+ };
556
+ };
557
+ const timezone = (0, _timezoneSoft.default)(this.getTimeZone());
558
+ if (timezone.length === 0) {
559
+ return {};
560
+ }
561
+ const {
562
+ daylight,
563
+ standard
564
+ } = timezone[0];
565
+ if (daylight) {
566
+ return {
567
+ daylight: createOffsetObject(daylight),
568
+ standard: createOffsetObject(standard)
569
+ };
570
+ }
571
+ return {
572
+ standard: createOffsetObject(standard)
573
+ };
574
+ }
376
575
  }
377
576
 
378
577
  /**