@openmrs/esm-utils 5.7.3-pre.2136 → 5.7.3-pre.2139
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.
- package/.turbo/turbo-build.log +11 -16
- package/dist/openmrs-esm-utils.js +1 -1
- package/dist/openmrs-esm-utils.js.map +1 -1
- package/package.json +2 -2
- package/src/age-helpers.test.ts +37 -0
- package/src/age-helpers.ts +41 -87
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-utils",
|
|
3
|
-
"version": "5.7.3-pre.
|
|
3
|
+
"version": "5.7.3-pre.2139",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Helper utilities for OpenMRS",
|
|
6
6
|
"browser": "dist/openmrs-esm-utils.js",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"access": "public"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@openmrs/esm-globals": "5.7.3-pre.
|
|
42
|
+
"@openmrs/esm-globals": "5.7.3-pre.2139",
|
|
43
43
|
"@types/semver": "^7.3.4",
|
|
44
44
|
"dayjs": "^1.10.4",
|
|
45
45
|
"rxjs": "^6.5.3"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import dayjs from 'dayjs';
|
|
2
|
+
import type { i18n } from 'i18next';
|
|
3
|
+
import { age } from '.';
|
|
4
|
+
|
|
5
|
+
window.i18next = { language: 'en' } as i18n;
|
|
6
|
+
|
|
7
|
+
describe('Age Helper', () => {
|
|
8
|
+
// test cases mostly taken from
|
|
9
|
+
// https://webarchive.nationalarchives.gov.uk/ukgwa/20160921162509mp_/http://systems.digital.nhs.uk/data/cui/uig/patben.pdf
|
|
10
|
+
// (Table 8)
|
|
11
|
+
const now = dayjs('2024-07-30');
|
|
12
|
+
const test1 = now.subtract(1, 'hour').subtract(30, 'minutes');
|
|
13
|
+
const test2 = now.subtract(1, 'day').subtract(2, 'hours').subtract(5, 'minutes');
|
|
14
|
+
const test3 = now.subtract(3, 'days').subtract(17, 'hours').subtract(30, 'minutes');
|
|
15
|
+
const test4 = now.subtract(27, 'days').subtract(5, 'hours').subtract(2, 'minutes');
|
|
16
|
+
const test5 = now.subtract(28, 'days').subtract(5, 'hours').subtract(2, 'minutes');
|
|
17
|
+
const test6 = now.subtract(29, 'days').subtract(5, 'hours').subtract(2, 'minutes');
|
|
18
|
+
const test7 = now.subtract(1, 'year').subtract(1, 'day').subtract(5, 'hours');
|
|
19
|
+
const test8 = now.subtract(1, 'year').subtract(8, 'day').subtract(5, 'hours');
|
|
20
|
+
const test9 = now.subtract(1, 'year').subtract(39, 'day').subtract(5, 'hours');
|
|
21
|
+
const test10 = now.subtract(4, 'year').subtract(39, 'day');
|
|
22
|
+
const test11 = now.subtract(18, 'year').subtract(39, 'day');
|
|
23
|
+
|
|
24
|
+
it('should render durations correctly', () => {
|
|
25
|
+
expect(age(test1, now)).toBe('90 min');
|
|
26
|
+
expect(age(test2, now)).toBe('26 hr');
|
|
27
|
+
expect(age(test3, now)).toBe('3 days');
|
|
28
|
+
expect(age(test4, now)).toBe('27 days');
|
|
29
|
+
expect(age(test5, now)).toBe('4 wks');
|
|
30
|
+
expect(age(test6, now)).toBe('4 wks, 1 day');
|
|
31
|
+
expect(age(test7, now)).toBe('12 mths, 1 day');
|
|
32
|
+
expect(age(test8, now)).toBe('12 mths, 8 days');
|
|
33
|
+
expect(age(test9, now)).toBe('13 mths, 9 days');
|
|
34
|
+
expect(age(test10, now)).toBe('4 yrs, 1 mth');
|
|
35
|
+
expect(age(test11, now)).toBe('18 yrs');
|
|
36
|
+
});
|
|
37
|
+
});
|
package/src/age-helpers.ts
CHANGED
|
@@ -1,101 +1,55 @@
|
|
|
1
1
|
/** @module @category Utility */
|
|
2
|
+
import dayjs from 'dayjs';
|
|
2
3
|
import { getLocale } from './omrs-dates';
|
|
4
|
+
import { DurationFormat } from '@formatjs/intl-durationformat';
|
|
5
|
+
import { type DurationInput } from '@formatjs/intl-durationformat/src/types';
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
|
-
* Gets
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
24 /
|
|
13
|
-
60 /
|
|
14
|
-
60 /
|
|
15
|
-
1000
|
|
16
|
-
);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Checks if two dates are representing the same day.
|
|
21
|
-
* @param firstDate The first date.
|
|
22
|
-
* @param secondDate The second date.
|
|
23
|
-
* @returns True if both are located on the same day.
|
|
24
|
-
*/
|
|
25
|
-
export function isSameDay(firstDate: Date, secondDate: Date) {
|
|
26
|
-
const firstISO = firstDate.toISOString();
|
|
27
|
-
const secondISO = secondDate.toISOString();
|
|
28
|
-
return firstISO.slice(0, firstISO.indexOf('T')) === secondISO.slice(0, secondISO.indexOf('T'));
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Gets a human readable and locale supported age represention of the provided date string.
|
|
33
|
-
* @param dateString The stringified date.
|
|
8
|
+
* Gets a human readable and locale supported representation of a person's age, given their birthDate,
|
|
9
|
+
* The representation logic follows the guideline here:
|
|
10
|
+
* https://webarchive.nationalarchives.gov.uk/ukgwa/20160921162509mp_/http://systems.digital.nhs.uk/data/cui/uig/patben.pdf
|
|
11
|
+
* (See Tables 7 and 8)
|
|
12
|
+
*
|
|
13
|
+
* @param birthDate The birthDate.
|
|
14
|
+
* @param currentDate Optional. If provided, calculates the age of the person at the provided currentDate (instead of now).
|
|
34
15
|
* @returns A human-readable string version of the age.
|
|
35
16
|
*/
|
|
36
|
-
export function age(
|
|
37
|
-
|
|
17
|
+
export function age(birthDate: dayjs.ConfigType, currentDate: dayjs.ConfigType = dayjs()): string {
|
|
18
|
+
const to = dayjs(currentDate);
|
|
19
|
+
const from = dayjs(birthDate);
|
|
38
20
|
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
let age = today.getUTCFullYear() - birthDate.getUTCFullYear();
|
|
45
|
-
if (monthDifference < 0 || (monthDifference === 0 && dateDifference < 0)) {
|
|
46
|
-
age--;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Now calculate the number of months in addition to the year's age
|
|
50
|
-
let monthsAgo = monthDifference >= 0 ? monthDifference : monthDifference + 12;
|
|
51
|
-
if (dateDifference < 0) {
|
|
52
|
-
monthsAgo--;
|
|
53
|
-
}
|
|
21
|
+
const hourDiff = to.diff(from, 'hours');
|
|
22
|
+
const dayDiff = to.diff(from, 'days');
|
|
23
|
+
const weekDiff = to.diff(from, 'weeks');
|
|
24
|
+
const monthDiff = to.diff(from, 'months');
|
|
25
|
+
const yearDiff = to.diff(from, 'years');
|
|
54
26
|
|
|
55
|
-
|
|
56
|
-
let totalDaysAgo = daysIntoYear(today) - daysIntoYear(birthDate);
|
|
57
|
-
if (totalDaysAgo < 0) {
|
|
58
|
-
totalDaysAgo += 365;
|
|
59
|
-
}
|
|
60
|
-
const weeksAgo = Math.floor(totalDaysAgo / 7);
|
|
27
|
+
const duration: DurationInput = {};
|
|
61
28
|
|
|
62
29
|
const locale = getLocale();
|
|
63
30
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
return weeksAgoStr;
|
|
84
|
-
}
|
|
85
|
-
} else if (age < 2) {
|
|
86
|
-
const monthsAgoStr = new Intl.NumberFormat(locale, {
|
|
87
|
-
style: 'unit',
|
|
88
|
-
unit: 'month',
|
|
89
|
-
unitDisplay: 'short',
|
|
90
|
-
}).format(monthsAgo + 12);
|
|
91
|
-
|
|
92
|
-
return monthsAgoStr;
|
|
31
|
+
if (hourDiff < 2) {
|
|
32
|
+
const minuteDiff = to.diff(from, 'minutes');
|
|
33
|
+
duration['minutes'] = minuteDiff;
|
|
34
|
+
} else if (dayDiff < 2) {
|
|
35
|
+
duration['hours'] = hourDiff;
|
|
36
|
+
} else if (weekDiff < 4) {
|
|
37
|
+
duration['days'] = dayDiff;
|
|
38
|
+
} else if (yearDiff < 1) {
|
|
39
|
+
const remainderDayDiff = to.subtract(weekDiff, 'weeks').diff(from, 'days');
|
|
40
|
+
duration['weeks'] = weekDiff;
|
|
41
|
+
duration['days'] = remainderDayDiff;
|
|
42
|
+
} else if (yearDiff < 2) {
|
|
43
|
+
const remainderDayDiff = to.subtract(monthDiff, 'months').diff(from, 'days');
|
|
44
|
+
duration['months'] = monthDiff;
|
|
45
|
+
duration['days'] = remainderDayDiff;
|
|
46
|
+
} else if (yearDiff < 18) {
|
|
47
|
+
const remainderMonthDiff = to.subtract(yearDiff, 'year').diff(from, 'months');
|
|
48
|
+
duration['years'] = yearDiff;
|
|
49
|
+
duration['months'] = remainderMonthDiff;
|
|
93
50
|
} else {
|
|
94
|
-
|
|
95
|
-
style: 'unit',
|
|
96
|
-
unit: 'year',
|
|
97
|
-
unitDisplay: 'short',
|
|
98
|
-
}).format(age);
|
|
99
|
-
return yearsAgoStr;
|
|
51
|
+
duration['years'] = yearDiff;
|
|
100
52
|
}
|
|
53
|
+
|
|
54
|
+
return new DurationFormat(locale, { style: 'short' }).format(duration);
|
|
101
55
|
}
|