nmce-func 1.3.2 → 1.4.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.
@@ -1,8 +1,4 @@
1
- import * as i0 from '@angular/core';
2
- import { Injectable, Inject } from '@angular/core';
3
- import { map } from 'rxjs/operators';
4
- import * as i1 from '@angular/common/http';
5
- import moment from 'moment';
1
+ import { DateTime, Settings, Duration } from 'luxon';
6
2
  import { v4 } from 'uuid';
7
3
 
8
4
  class AddressFunc {
@@ -54,67 +50,26 @@ class AddressFunc {
54
50
  }
55
51
  }
56
52
 
57
- /**
58
- * Login and saving tokens in sessionStorage.
59
- * App needs to provide constant 'auth.tokenUrl'.
60
- */
61
- class AuthenticationService {
62
- authUri;
63
- http;
64
- username;
65
- constructor(authUri, http) {
66
- this.authUri = authUri;
67
- this.http = http;
68
- }
69
- /**
70
- * Login and save tokens to sessionStorage then return an observable.
71
- * @param username
72
- * @param password
73
- */
74
- login(username, password, headers) {
75
- const body = 'username=' + username + '&password=' + password + '&grant_type=password';
76
- const contentTypeHeader = { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' };
77
- const mergedHeaders = headers ? { ...contentTypeHeader, ...headers } : contentTypeHeader;
78
- const options = { headers: mergedHeaders };
79
- return this.http.post(this.authUri, body, options)
80
- .pipe(map(response => {
81
- //sessionStorage.setItem('access_token', response.access_token); The client code is response to doing these.
82
- //sessionStorage.setItem('expires_in', response.expires_in.toString());
83
- //sessionStorage.setItem('token_type', response.token_type);
84
- //sessionStorage.setItem('issued', response.issued);
85
- //sessionStorage.setItem('expires', response.expires); // often up to 2 weeks by default in Asp.net identity 2.
86
- this.username = response.username;
87
- //APP_STATUSES.userName = this.userName;
88
- return response;
89
- }));
90
- }
91
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: AuthenticationService, deps: [{ token: 'auth.tokenUrl' }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
92
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: AuthenticationService });
93
- }
94
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: AuthenticationService, decorators: [{
95
- type: Injectable
96
- }], ctorParameters: () => [{ type: undefined, decorators: [{
97
- type: Inject,
98
- args: ['auth.tokenUrl']
99
- }] }, { type: i1.HttpClient }] });
100
-
101
53
  /**
102
54
  * Currency calculations. Undefined input of number is considered zero, just like null.
55
+ * Simple functions for currency before you decide to use more comprehensive ones:
56
+ * https://github.com/scurker/currency.js
57
+ * https://github.com/dinerojs/dinero.js Up to date and popular
103
58
  */
104
59
  class CurrencyFunc {
105
60
  static DECIMAL_SEPARATOR = '.';
106
61
  static THOUSANDS_SEPARATOR = ',';
107
62
  static PADDING = '000000';
108
63
  /**
109
- *
64
+ * Banker rounding
110
65
  * @param num
111
- * @param decimalPlaces default 0
66
+ * @param decimalPlace default 0
112
67
  */
113
- static bankerRound(num, decimalPlaces) {
68
+ static bankerRound(num, decimalPlace) {
114
69
  if (!num) {
115
70
  return 0;
116
71
  }
117
- const d = decimalPlaces || 0;
72
+ const d = decimalPlace || 0;
118
73
  const m = Math.pow(10, d);
119
74
  const n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
120
75
  const i = Math.floor(n), f = n - i;
@@ -122,48 +77,57 @@ class CurrencyFunc {
122
77
  const r = (f > 0.5 - e && f < 0.5 + e) ?
123
78
  ((i % 2 === 0) ? i : i + 1) : Math.round(n);
124
79
  return d ? r / m : r;
80
+ // http://stackoverflow.com/questions/3108986/gaussian-bankers-rounding-in-javascript
125
81
  }
82
+ /**
83
+ * Banker rounding to 5 cents
84
+ * @param num
85
+ * @returns
86
+ */
126
87
  static bankerRoundTo5cents(num) {
127
88
  if (!num) {
128
89
  return 0;
129
90
  }
130
- const r = this.bankerRound(Math.ceil(num * 20 - 0.5) / 20, 2);
91
+ const r = this.bankerRound(Math.round(num / 0.05) * 0.05, 2);
131
92
  return r;
132
93
  }
133
- static ceilTo5cents(num) {
134
- if (!num) {
135
- return 0;
136
- }
137
- const r = this.bankerRound(Math.ceil(num * 20) / 20, 4);
138
- const roundup = Math.ceil(r * 10000) / 10000;
139
- return roundup;
140
- }
141
- static transformCurrency(value, fractionSize = 2) {
142
- let [integer, fraction = ''] = (value || '').toString()
143
- .split(this.DECIMAL_SEPARATOR);
144
- fraction = fractionSize > 0
145
- ? this.DECIMAL_SEPARATOR + (fraction + this.PADDING).substring(0, fractionSize)
146
- : '';
147
- integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, this.THOUSANDS_SEPARATOR);
148
- return integer + fraction;
149
- }
150
- static parseCurrency(value, fractionSize = 2) {
151
- let [integer, fraction = ''] = (value || '').split(this.DECIMAL_SEPARATOR);
152
- integer = integer.replace(new RegExp(this.THOUSANDS_SEPARATOR, 'g'), '');
153
- fraction = parseInt(fraction, 10) > 0 && fractionSize > 0
154
- ? this.DECIMAL_SEPARATOR + (fraction + this.PADDING).substring(0, fractionSize)
155
- : '';
156
- return integer + fraction;
157
- }
94
+ // static transformCurrency(value: number | string | undefined, fractionSize: number = 2): string { In favour of dinerojs
95
+ // let [integer, fraction = ''] = (value || '').toString()
96
+ // .split(this.DECIMAL_SEPARATOR);
97
+ // fraction = fractionSize > 0
98
+ // ? this.DECIMAL_SEPARATOR + (fraction + this.PADDING).substring(0, fractionSize)
99
+ // : '';
100
+ // integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, this.THOUSANDS_SEPARATOR);
101
+ // return integer + fraction;
102
+ // }
103
+ // static parseCurrency(value: string | undefined, fractionSize: number = 2): string {
104
+ // let [integer, fraction = ''] = (value || '').split(this.DECIMAL_SEPARATOR);
105
+ // integer = integer.replace(new RegExp(this.THOUSANDS_SEPARATOR, 'g'), '');
106
+ // fraction = parseInt(fraction, 10) > 0 && fractionSize > 0
107
+ // ? this.DECIMAL_SEPARATOR + (fraction + this.PADDING).substring(0, fractionSize)
108
+ // : '';
109
+ // return integer + fraction;
110
+ // }
158
111
  //http://stackoverflow.com/questions/2998784/how-to-output-integers-with-leading-zeros-in-javascript
159
112
  static pad(num, size) {
160
- num = null;
161
- let s = num + '';
113
+ if (num == null) {
114
+ return '';
115
+ }
116
+ if (num === 0) {
117
+ return '0';
118
+ }
119
+ const numText = num.toString();
120
+ let s = numText + '';
162
121
  while (s.length < size) {
163
122
  s = '0' + s;
164
123
  }
165
124
  return s;
166
125
  }
126
+ /**
127
+ * Sum array of numbers
128
+ * @param ns
129
+ * @returns
130
+ */
167
131
  static sum(ns) {
168
132
  const r = ns.reduce((a, b) => (a ?? 0) + (b ?? 0), 0);
169
133
  return r;
@@ -171,100 +135,156 @@ class CurrencyFunc {
171
135
  }
172
136
 
173
137
  class DateFunc {
138
+ /**
139
+ * At runtime, there's no simple guarantee that the input is Date. Sometimes you codes expect date, but the response from the Web service may give you string or number.
140
+ * This function give you safe parse of date data from I/O, not of your control.
141
+ * If the data is invalid, throws RangeError or TypeError.
142
+ * @param dt
143
+ * @returns
144
+ */
145
+ static dateDataToDate(dt) {
146
+ if (dt instanceof Date) {
147
+ return dt;
148
+ }
149
+ if (typeof dt === 'string') {
150
+ const r = Date.parse(dt);
151
+ if (isNaN(r)) {
152
+ throw new RangeError('Invalid string for Date');
153
+ }
154
+ return new Date(r);
155
+ }
156
+ if (typeof dt === 'number') {
157
+ const rd = new Date(dt);
158
+ if (Number.isNaN(rd.valueOf())) {
159
+ throw new RangeError('Invalid number for Date');
160
+ }
161
+ return rd;
162
+ }
163
+ throw new TypeError('Expect Date, string or number');
164
+ }
165
+ /**
166
+ * Similar to dateDataToDate, but allow null and defined semantically.
167
+ * @param dt
168
+ * @returns
169
+ */
170
+ static dateDataToDateOrNull(dt) {
171
+ if (dt instanceof Date) {
172
+ return dt;
173
+ }
174
+ if (typeof dt === 'string') {
175
+ const r = Date.parse(dt);
176
+ if (isNaN(r)) {
177
+ throw new RangeError('Invalid string for Date');
178
+ }
179
+ return new Date(r);
180
+ }
181
+ if (typeof dt === 'number') {
182
+ const rd = new Date(dt);
183
+ if (Number.isNaN(rd.valueOf())) {
184
+ throw new RangeError('Invalid number for Date');
185
+ }
186
+ return rd;
187
+ }
188
+ if (dt == null) {
189
+ return dt;
190
+ }
191
+ throw new TypeError('Expect Date, string or number');
192
+ }
174
193
  /**
175
194
  * Transform UTC DateTime to local date without H, M and S. For example, the month day of 2018-01-23T22:00:00Z is 24 in Australia.
176
195
  * @param dtUtc
177
- * @param offsetMinutes if not defined, it will be new Date().getTimezoneOffset(). //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
178
196
  */
179
197
  static dateTimeUtcToLocalDateNumber(dtUtc) {
180
- if (!dtUtc) {
181
- return 0; //0 is better for calculation by the clients.
198
+ if (dtUtc == null) {
199
+ return dtUtc;
182
200
  }
183
- const localDt = DateFunc.dateTimeUtcToLocalDateTime(dtUtc);
201
+ const localDt = this.dateDataToDate(dtUtc);
184
202
  const localDNum = localDt.setHours(0, 0, 0, 0);
185
203
  return localDNum;
186
204
  }
187
205
  /**
188
206
  * Date only. However, the date may still be in UTC.
189
207
  * @param dtUtc
208
+ * @returns new Date object.
190
209
  */
191
210
  static dateTimeUtcToLocalDate(dtUtc) {
192
- const localDt = DateFunc.dateTimeUtcToLocalDateTime(dtUtc);
193
- const localD = localDt.setHours(0, 0, 0, 0);
194
- return new Date(localD);
211
+ if (dtUtc == null) {
212
+ return dtUtc;
213
+ }
214
+ const localDt = this.dateDataToDate(dtUtc);
215
+ const localNum = localDt.setHours(0, 0, 0, 0);
216
+ return new Date(localNum);
195
217
  }
218
+ /**
219
+ * '2018-01-23T22:00:00Z' will become '2018-01-24' in Australia.
220
+ * @param dtUtc
221
+ * @returns new Date object.
222
+ */
196
223
  static localISODateString(dtUtc) {
197
- const dt = moment(dtUtc).local();
198
- return dt.format('YYYY-MM-DD');
224
+ const dt = this.dateTimeUtcToLocalDate(dtUtc);
225
+ if (dt == null) {
226
+ return dt;
227
+ }
228
+ const d = DateTime.fromJSDate(dt);
229
+ return d.toISODate();
199
230
  }
200
231
  /**
201
- * locate date ONLY (no time) to UTC date.
232
+ * local date ONLY (no time) to UTC date.
233
+ * The input could be a string of yyyy-MM-dd, or a Date Object.
234
+ * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
235
+ * While the time value at the heart of a Date object is UTC, the basic methods to fetch the date and time
236
+ * or its components all work in the local (i.e. host system) time zone and offset.
202
237
  * @param dt if dt contain time info, it will become dt.setHours(0, 0, 0, 0)
203
238
  */
204
239
  static localDateToUtc(d) {
205
- const dt = moment(d).toDate();
240
+ if (d == null) {
241
+ return d;
242
+ }
243
+ const dt = this.dateDataToDate(d);
206
244
  const n = dt.setHours(0, 0, 0, 0);
207
245
  const offset = dt.getTimezoneOffset() * 60000;
208
246
  return new Date(n + offset);
209
247
  }
210
- static getTimezoneOffset() {
211
- const dt = this.today;
212
- return dt.getTimezoneOffset();
213
- }
214
- /**
215
- * Transform UTC DateTime to local dateTime.
216
- * @param dtUtc
217
- * @param offsetMinutes if not defined, it will be new Date().getTimezoneOffset(). //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
218
- */
219
- static dateTimeUtcToLocalDateTime(dtUtc) {
220
- const stillUtc = moment.utc(dtUtc).toDate();
221
- return moment(stillUtc).local().toDate();
222
- }
223
- static dateTimeUtcToLocaMoment(dtUtc) {
224
- const stillUtc = moment.utc(dtUtc);
225
- return stillUtc.local();
226
- }
227
248
  static getEndOfWeek(dt) {
228
- return moment(dt).endOf('isoWeek').toDate();
249
+ const dateTime = DateTime.fromJSDate(this.dateDataToDate(dt));
250
+ return dateTime.endOf('week').toJSDate();
229
251
  }
230
252
  static getStartOfWeek(dt) {
231
- return moment(dt).startOf('isoWeek').toDate();
253
+ const dateTime = DateTime.fromJSDate(this.dateDataToDate(dt));
254
+ return dateTime.startOf('week').toJSDate();
232
255
  }
233
256
  static getEndOfMonth(dt) {
234
- // return new Date(dt.getFullYear(), dt.getMonth() + 1, 0, 23, 59, 59, 999);
235
- return moment(dt).endOf('month').toDate();
257
+ const dateTime = DateTime.fromJSDate(this.dateDataToDate(dt));
258
+ return dateTime.endOf('month').toJSDate();
236
259
  }
237
260
  static getStartOfMonth(dt) {
238
- return moment(dt).startOf('month').toDate();
239
- }
240
- static getDaysBetweenDates(dt1, dt2) {
241
- return this.getDaysBetween(dt1, dt2);
261
+ const dateTime = DateTime.fromJSDate(this.dateDataToDate(dt));
262
+ return dateTime.startOf('month').toJSDate();
242
263
  }
243
264
  static getEndOfDate(dt) {
244
- return dt ? new Date(dt.setHours(23, 59, 59, 999)) :
245
- new Date(this.now.setHours(23, 59, 59, 999));
265
+ const dateTime = DateTime.fromJSDate(this.dateDataToDate(dt));
266
+ return dateTime.endOf('day').toJSDate();
246
267
  }
247
268
  static getStartOfDate(dt) {
248
- return moment(dt).startOf('day').toDate();
269
+ const dateTime = DateTime.fromJSDate(this.dateDataToDate(dt));
270
+ return dateTime.startOf('day').toJSDate();
249
271
  }
250
272
  static getEndOfToday() {
251
- // return new Date((new Date(Date.now())).setHours(23, 59, 59, 999));
252
- return moment(Date.now()).endOf('day').toDate();
273
+ return this.getEndOfDate(Date.now());
253
274
  }
254
275
  static getStartOfToday() {
255
- // return new Date((new Date(Date.now())).setHours(0, 0, 0, 0));
256
- return moment(Date.now()).startOf('day').toDate();
276
+ return this.getStartOfDate(Date.now());
257
277
  }
258
- //inspired https://stackoverflow.com/questions/563406/add-days-to-javascript-date
259
- static addDays(dt, days = 0) {
260
- const dat = moment(dt);
261
- dat.add(days, 'days');
262
- return dat.toDate();
278
+ static getDaysBetween(d1, d2) {
279
+ const dm1 = DateTime.fromJSDate(this.dateDataToDate(d1));
280
+ const dm2 = DateTime.fromJSDate(this.dateDataToDate(d1));
281
+ return dm2.diff(dm1, 'days').days;
263
282
  }
264
- static subtractDays(dt, days = 0) {
265
- const dat = moment(dt);
266
- dat.subtract(days, 'days');
267
- return dat.toDate();
283
+ //inspired https://stackoverflow.com/questions/563406/add-days-to-javascript-date
284
+ static addDays(dt, days) {
285
+ const dat = DateTime.fromJSDate(this.dateDataToDate(dt));
286
+ const r = dat.plus({ days: days });
287
+ return r.toJSDate();
268
288
  }
269
289
  /**
270
290
  * Start of today
@@ -275,104 +295,119 @@ class DateFunc {
275
295
  static get now() {
276
296
  return new Date(Date.now());
277
297
  }
298
+ /**
299
+ * From now, next 5 minute mark. For example 2:23:44 will be 2:25:00;
300
+ * @returns
301
+ */
278
302
  static getNext5MinuteMark() {
279
- const m = moment().set('second', 0).set('millisecond', 0);
280
- const minute = m.minute();
303
+ const m = DateTime.now().set({ second: 0, millisecond: 0 });
304
+ const minute = m.minute;
281
305
  const mod = minute % 5;
282
306
  if (mod) {
283
307
  const delta = 5 - mod;
284
- return m.add(delta, 'm').toDate();
308
+ return m.plus({ minutes: delta }).toJSDate();
285
309
  }
286
- return m.toDate();
310
+ return m.toJSDate();
287
311
  }
288
312
  static getYMD(d) {
289
- return moment(d).format('YYYYMMDD');
313
+ const dt = DateTime.fromJSDate(this.dateDataToDate(d));
314
+ return dt.toFormat('yyyyMMdd');
290
315
  }
291
316
  static getDMYWithSlash(d) {
292
- return moment(d).format('DD/MM/YYYY');
317
+ const dt = DateTime.fromJSDate(this.dateDataToDate(d));
318
+ return dt.toFormat('dd/MM/yyyy');
293
319
  }
294
320
  static getDMYHmWithSlash(d) {
295
- return moment(d).format('DD/MM/YYYY HH:mm');
296
- }
297
- static getMcpTime(dt) {
298
- return moment(dt).format('HH:mm:ss.SSSZ');
321
+ const dt = DateTime.fromJSDate(this.dateDataToDate(d));
322
+ return dt.toFormat('dd/MM/yyyy HH:mm');
299
323
  }
300
324
  /**
301
- * In 24 hour format
302
- * @param dtUtc
325
+ *
326
+ * @param dtUtc In 24 hour format, and the date separator depending on the system or Luxon default locale
327
+ * @returns
303
328
  */
304
- static getLocalDMYHmWithSlash(dtUtc) {
305
- const d = DateFunc.dateTimeUtcToLocalDateTime(dtUtc);
306
- return moment(d).format('DD/MM/YYYY HH:mm');
329
+ static getDateTime24Simple(dtUtc) {
330
+ if (dtUtc == null) {
331
+ return dtUtc;
332
+ }
333
+ const d = this.dateDataToDate(dtUtc);
334
+ const dt = DateTime.fromJSDate(d);
335
+ return dt.toLocaleString(DateTime.DATE_SHORT) + ' ' + dt.toLocaleString(DateTime.TIME_24_SIMPLE);
336
+ }
337
+ static setDefaultLocale(locale) {
338
+ Settings.defaultLocale = locale;
339
+ }
340
+ static getDefaultLocale() {
341
+ return Settings.defaultLocale;
342
+ }
343
+ static setDefaultZone(zone) {
344
+ Settings.defaultZone = zone;
345
+ }
346
+ static getDefaultZone() {
347
+ return Settings.defaultZone.name;
348
+ }
349
+ static isZoneValid() {
350
+ return Settings.defaultZone.isValid;
307
351
  }
308
352
  /**
309
- * Offset minutes comparing with today
353
+ * For example, in AEST, it is -600.
354
+ * @returns
310
355
  */
311
- static getOffsetMinutes(dtUtc) {
312
- const dm1 = moment(dtUtc);
313
- const dm2 = moment(new Date().setHours(0, 0, 0, 0));
314
- return dm1.diff(dm2, 'minutes');
315
- }
316
- static getDaysBetween(d1, d2) {
317
- const dm1 = moment(d1);
318
- const dm2 = moment(d2);
319
- return dm2.diff(dm1, 'days');
356
+ static getLocalTimezoneOffset() {
357
+ const dt = new Date(Date.now());
358
+ return dt.getTimezoneOffset();
320
359
  }
321
360
  /**
322
361
  * Get hour of the date. If Date is not defined, the hour will be current hour.
323
362
  * @param dtUtc
324
363
  */
325
364
  static getHour(dtUtc) {
326
- const m = moment(dtUtc);
327
- return m.hours();
365
+ const dt = DateTime.fromJSDate(this.dateDataToDate(dtUtc));
366
+ return dt.hour;
328
367
  }
329
368
  static getMinute(dtUtc) {
330
- const m = moment(dtUtc);
331
- return m.minutes();
369
+ const dt = DateTime.fromJSDate(this.dateDataToDate(dtUtc));
370
+ return dt.minute;
332
371
  }
333
- static composeDateTime(dt, h = 0, minute = 0) {
334
- const mt = moment(dt);
335
- return new Date(mt.toDate().setHours(h, minute, 0, 0));
372
+ static GetHM(dtUtc) {
373
+ const dt = DateTime.fromJSDate(this.dateDataToDate(dtUtc));
374
+ return { h: dt.hour, m: dt.minute };
336
375
  }
337
- static olderThan24Hours(d) {
338
- const m = moment(d);
339
- return moment().diff(m, 'hours') >= 24;
376
+ static composeDateTime(dt, h = 0, minute = 0, second = 0) {
377
+ return new Date(this.dateDataToDate(dt).setHours(h, minute, second, 0));
340
378
  }
341
- static olderThan24HoursUtc(dtUtc) {
342
- return DateFunc.getHourAgeUtc(dtUtc) >= 24;
379
+ static olderThan24Hours(d) {
380
+ const m = DateTime.fromJSDate(this.dateDataToDate(d));
381
+ return DateTime.now().diff(m, 'hours') >= Duration.fromISO('PT24H');
343
382
  }
344
383
  static olderThanHours(d, hours) {
345
- const m = moment(d);
346
- return moment().diff(m, 'hours') >= hours;
347
- }
348
- static olderThanHoursUtc(dtUtc, hours) {
349
- return DateFunc.getHourAgeUtc(dtUtc) >= hours;
384
+ const m = DateTime.fromJSDate(this.dateDataToDate(d));
385
+ const diff = DateTime.now().diff(m, 'hours');
386
+ const duration = Duration.fromISO(`PT${hours}H`);
387
+ console.debug('diff: ' + diff.hours + ' duration: ' + duration.hours);
388
+ return diff.hours >= duration.hours;
350
389
  }
351
390
  static olderThanMinutes(d, minutes) {
352
- const m = moment(d);
353
- return moment().diff(m, 'minutes') >= minutes;
391
+ const m = DateTime.fromJSDate(this.dateDataToDate(d));
392
+ return DateTime.now().diff(m, 'minutes') >= Duration.fromMillis(minutes * 60 * 1000);
354
393
  }
355
394
  /**
356
395
  * It could be 11PM yesterday, and 1 AM today. Actually based on local today.
357
396
  */
358
397
  static olderThan1Day(dtUtc) {
359
- return DateFunc.getDayAgeUtc(dtUtc) > 0;
398
+ return DateFunc.getDayAge(dtUtc) > 0;
360
399
  }
361
400
  static getHourAge(d) {
362
- const m = moment(d);
363
- return moment().diff(m, 'hours');
364
- }
365
- static getHourAgeUtc(dtUtc) {
366
- const m = moment.utc(dtUtc);
367
- return moment.utc().diff(m, 'hours');
401
+ const m = DateTime.fromJSDate(this.dateDataToDate(d));
402
+ return DateTime.now().diff(m, 'hours').hours;
368
403
  }
369
404
  /**
370
- * Compare utc date with utc now.
405
+ * Compare date with now.
371
406
  * @param dtUtc
372
407
  */
373
- static getDayAgeUtc(dtUtc) {
374
- const m = moment.utc(dtUtc);
375
- return moment.utc().diff(m, 'days');
408
+ static getDayAge(d) {
409
+ const m = DateTime.fromJSDate(this.dateDataToDate(d));
410
+ return DateTime.now().diff(m, 'days').days;
376
411
  }
377
412
  /**
378
413
  * How many years from now.
@@ -380,108 +415,29 @@ class DateFunc {
380
415
  * @returns
381
416
  */
382
417
  static getAge(d) {
383
- const m = moment(d);
384
- return moment().diff(m, 'years');
385
- }
386
- /**
387
- * Year of date.
388
- * @param d
389
- * @returns
390
- */
391
- static getYear(d) {
392
- const m = moment(d);
393
- return m.year();
394
- }
395
- static getUtcNow() {
396
- return moment.utc().toDate();
397
- }
398
- static addMinutes(d, m) {
399
- return moment(d).add(m, 'm').toDate();
400
- }
401
- static addMonth(d, m) {
402
- return moment(d).add(m, 'M').toDate();
403
- }
404
- static getDuration(d1, d2) {
405
- const md1 = moment(d1);
406
- const md2 = moment(d2);
407
- return moment.duration(md2.diff(md1));
418
+ const m = DateTime.fromJSDate(this.dateDataToDate(d));
419
+ return DateTime.now().diff(m, 'years').years;
408
420
  }
409
421
  /**
410
422
  * Convert minutes from midnight to HH:mm text
411
- * @param mins
423
+ * @param minutes
412
424
  */
413
- static getHMFromMins(mins) {
414
- // do not include the first validation check if you want, for example,
415
- // getTimeFromMins(1530) to equal getTimeFromMins(90) (i.e. mins rollover)
416
- if (mins >= 24 * 60 || mins < 0) {
425
+ static getHMFromMins(minutes) {
426
+ if (minutes >= 24 * 60 || minutes < 0) {
417
427
  throw new RangeError('Valid input should be greater than or equal to 0 and less than 1440.');
418
428
  }
419
- const h = mins / 60 | 0, m = mins % 60 | 0;
420
- return moment.utc().hours(h).minutes(m).format('HH:mm');
429
+ const h = minutes / 60 | 0, m = minutes % 60 | 0;
430
+ return DateTime.utc().set({ hour: h, minute: m }).toFormat('HH:mm');
421
431
  }
422
432
  static getMinutesSinceMidnight(d) {
423
- const m = moment(d);
424
- const midnight = moment(d).startOf('day'); //Mutates the original moment by setting it to the start of a unit of time. So I have better not to use m which wil be changed by calling this function
425
- return m.diff(midnight, 'minutes');
433
+ const dt = DateTime.fromJSDate(this.dateDataToDate(d));
434
+ const midnight = dt.startOf('day');
435
+ return dt.diff(midnight, 'minutes').minutes;
426
436
  }
427
437
  static getMinutesBetween(start, end) {
428
- const m = moment(start);
429
- const m2 = moment(end);
430
- return m2.diff(m, 'minutes');
431
- }
432
- /**
433
- * Parse json string with date serialized into string, and get proper date object back
434
- * @param s
435
- */
436
- static dateSafeJsonParse(s) {
437
- return JSON.parse(s, this.dateReviver);
438
- }
439
- static dateReviver(key, value) {
440
- if (DateFunc.isSerializedDate(value)) {
441
- return (new Date(value));
442
- }
443
- // If it's not a date-string, we want to return the value as-is. If we fail to return
444
- // a value, it will be omitted from the resultant data structure.
445
- return (value);
446
- }
447
- // I determine if the given value is a string that matches the serialized-date pattern.
448
- static isSerializedDate(value) {
449
- // Dates are serialized in TZ format, example: '1981-12-20T04:00:14.000Z'.
450
- const datePattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
451
- return (DateFunc.isString(value) && datePattern.test(value));
452
- }
453
- // I determine if the given value is a String.
454
- static isString(value) {
455
- return ({}.toString.call(value) === '[object String]');
456
- }
457
- static dateSafeParse(s) {
458
- const m = moment(s);
459
- return m.toDate();
460
- }
461
- static composeDateWithMinutes(d, minute) {
462
- const m = moment(d);
463
- const midnight = moment(d).startOf('day'); // Mutates the original moment by setting it to the start of a unit of time. So I have better not to use m which wil be changed by calling this function
464
- midnight.add(minute, 'minutes');
465
- return midnight.toDate();
466
- }
467
- /**
468
- * Safe compare since date data may be considered as string rather than date.
469
- * @param d1
470
- * @param d2
471
- */
472
- static compare(d1, d2) {
473
- if (!d1 && !d2) {
474
- return 0;
475
- }
476
- if (!d1) {
477
- return -NaN;
478
- }
479
- if (!d2) {
480
- return NaN;
481
- }
482
- const dd1 = (new Date(d1)).valueOf();
483
- const dd2 = (new Date(d2)).valueOf();
484
- return dd1 - dd2;
438
+ const m = DateTime.fromJSDate(this.dateDataToDate(start));
439
+ const m2 = DateTime.fromJSDate(this.dateDataToDate(end));
440
+ return m2.diff(m, 'minutes').minutes;
485
441
  }
486
442
  }
487
443
 
@@ -493,9 +449,9 @@ class HtmlPrintFunc {
493
449
  */
494
450
  static printWithCSS(htmlTags, cssUrl) {
495
451
  if (window) {
496
- const htmlToPrint = `<html><head>
497
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
498
- <link rel="stylesheet" type="text/css" href="${cssUrl}" media="screen,print"/>
452
+ const htmlToPrint = `<html><head>
453
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
454
+ <link rel="stylesheet" type="text/css" href="${cssUrl}" media="screen,print"/>
499
455
  </head><body onload="window.print()">${htmlTags}</body></html>`;
500
456
  const popup = window.open('', '_blank', 'width=1024,height=768');
501
457
  popup?.document.open();
@@ -510,8 +466,8 @@ class HtmlPrintFunc {
510
466
  */
511
467
  static print(htmlTags) {
512
468
  if (window) {
513
- const htmlToPrint = `<html><head>
514
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
469
+ const htmlToPrint = `<html><head>
470
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
515
471
  </head><body onload="window.print()">${htmlTags}</body></html>`;
516
472
  const popup = window.open('', '_blank', 'width=1024,height=768');
517
473
  popup?.document.open();
@@ -581,10 +537,12 @@ class JsonFunc {
581
537
  static groupByDate(array, propertyName) {
582
538
  return array.reduce(function (acc, obj) {
583
539
  const key = DateFunc.dateTimeUtcToLocalDateNumber(obj[propertyName]);
584
- if (!acc[key]) {
585
- acc[key] = [];
540
+ if (key != null) {
541
+ if (!acc[key]) {
542
+ acc[key] = [];
543
+ }
544
+ acc[key].push(obj);
586
545
  }
587
- acc[key].push(obj);
588
546
  return acc;
589
547
  }, {});
590
548
  }
@@ -910,14 +868,12 @@ class StringFunc {
910
868
  }
911
869
  }
912
870
 
913
- // import { v5 as uuid } from 'uuid/v5 causes ERROR in src / app / _func / helperFunc.ts(1, 10): error TS2305: Module '"C:/VSProjects/ApsCloudTrunk/APS.WebPos.NGCli/NGSource/node_modules/@types/uuid/v5"' has no exported member 'v5'
914
871
  // https://github.com/DefinitelyTyped/DefinitelyTyped/pull/28439
915
872
  class UuidFunc {
916
873
  /**
917
874
  * 36 UUID string including 4 hyphens. MySql stores GUID as 36 bytes anyway rather than 16bytes.
918
875
  */
919
876
  static newUUID() {
920
- // return uuid('medilink.com.au', 'apscloud');
921
877
  return v4();
922
878
  }
923
879
  static newUUIDStartWith0() {
@@ -934,5 +890,5 @@ class UuidFunc {
934
890
  * Generated bundle index. Do not edit.
935
891
  */
936
892
 
937
- export { AddressFunc, AuthenticationService, CurrencyFunc, DateFunc, HtmlPrintFunc, JavaScriptFunc, JsonFunc, StringAusFunc, StringFunc, UuidFunc };
893
+ export { AddressFunc, CurrencyFunc, DateFunc, HtmlPrintFunc, JavaScriptFunc, JsonFunc, StringAusFunc, StringFunc, UuidFunc };
938
894
  //# sourceMappingURL=nmce-func.mjs.map