@brightspace-ui/intl 3.12.0 → 3.13.1

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 (2) hide show
  1. package/lib/dateTime.js +72 -0
  2. package/package.json +2 -2
package/lib/dateTime.js CHANGED
@@ -1167,3 +1167,75 @@ export function formatTimeFromTimestamp(timestamp, options) {
1167
1167
  const date = parseLocalDateTimeFromTimestamp(timestamp);
1168
1168
  return formatTime(date, options);
1169
1169
  }
1170
+
1171
+ export function formatRelativeDateTime(then) {
1172
+
1173
+ const now = new Date();
1174
+ const { firstDayOfWeek } = getDateTimeDescriptor().calendar;
1175
+
1176
+ if (!Intl.RelativeTimeFormat) {
1177
+ return now.toDateString() === then.toDateString() ? formatTime(then) : formatDate(then);
1178
+ }
1179
+
1180
+ const delta = (then.getTime() - now.getTime()) / 1000;
1181
+
1182
+ const unitCutoffs = {
1183
+ second: 60,
1184
+ minute: 60,
1185
+ hour: 24,
1186
+ day: 7,
1187
+ week: 4.348,
1188
+ month: 12,
1189
+ year: 0
1190
+ };
1191
+
1192
+ let { value, unit } = Object.entries(unitCutoffs).reduce(({ value }, [ unit, cutoff ], idx, arr) => {
1193
+ if (cutoff && Math.round(Math.abs(value)) >= Math.round(cutoff)) return { value: value / cutoff };
1194
+ arr.splice(idx + 1); // short-circuit
1195
+ return { value, unit };
1196
+ }, { value: delta });
1197
+
1198
+ let numeric = 'always';
1199
+ const thenTS = then.getTime();
1200
+
1201
+ if (unit === 'week' || unit === 'day' && Math.round(Math.abs(value)) >= 4) {
1202
+
1203
+ const fullWeek = 7 * 24 * 60 * 60 * 1000;
1204
+ const thisWeek = (d => {
1205
+ d.setDate(d.getDate() - d.getDay() + firstDayOfWeek);
1206
+ d.setHours(0, 0, 0, 0);
1207
+ return d.getTime();
1208
+ })(new Date(now));
1209
+
1210
+ const lastWeek = thenTS < thisWeek && thenTS >= (thisWeek - fullWeek);
1211
+ const nextWeek = thenTS >= thisWeek + fullWeek && thenTS < (thisWeek + fullWeek * 2);
1212
+
1213
+ if (lastWeek || nextWeek) {
1214
+ numeric = 'auto';
1215
+ unit = 'week';
1216
+ value = Math.sign(value);
1217
+ }
1218
+ }
1219
+ else if (unit === 'day' || unit === 'hour' && Math.round(Math.abs(value)) >= 6) {
1220
+
1221
+ const fullDay = 24 * 60 * 60 * 1000;
1222
+ const today = new Date(now.toDateString()).getTime();
1223
+
1224
+ const yesterday = thenTS < today && thenTS >= (today - fullDay);
1225
+ const tomorrow = thenTS >= today + fullDay && thenTS < (today + fullDay * 2);
1226
+
1227
+ if (yesterday || tomorrow) {
1228
+ numeric = 'auto';
1229
+ unit = 'day';
1230
+ value = Math.sign(value);
1231
+ }
1232
+ }
1233
+
1234
+ const rtf = new Intl.RelativeTimeFormat(getLanguage(), {
1235
+ localeMatcher: 'best fit',
1236
+ style: 'long',
1237
+ numeric
1238
+ });
1239
+
1240
+ return rtf.format(Math.round(value), unit);
1241
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/intl",
3
- "version": "3.12.0",
3
+ "version": "3.13.1",
4
4
  "description": "Internationalization APIs for number, date, time and file size formatting and parsing in D2L Brightspace.",
5
5
  "main": "lib/number.js",
6
6
  "scripts": {
@@ -42,7 +42,7 @@
42
42
  "chai": "^4",
43
43
  "concurrently": "^7",
44
44
  "eslint": "^8",
45
- "eslint-config-brightspace": "^0.19",
45
+ "eslint-config-brightspace": "^0.20",
46
46
  "http-server": "^14.0",
47
47
  "mocha": "^10",
48
48
  "mocha-headless-chrome": "^4"