@jsenv/humanize 1.7.0 → 1.7.2
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.
|
@@ -993,48 +993,90 @@ const setDecimalsPrecision = (
|
|
|
993
993
|
// return numberTruncated
|
|
994
994
|
// }
|
|
995
995
|
|
|
996
|
-
const
|
|
996
|
+
const UNIT_MS = {
|
|
997
|
+
year: 31_557_600_000,
|
|
998
|
+
month: 2_629_000_000,
|
|
999
|
+
week: 604_800_000,
|
|
1000
|
+
day: 86_400_000,
|
|
1001
|
+
hour: 3_600_000,
|
|
1002
|
+
minute: 60_000,
|
|
1003
|
+
second: 1000,
|
|
1004
|
+
};
|
|
1005
|
+
const UNIT_KEYS = Object.keys(UNIT_MS);
|
|
1006
|
+
const SMALLEST_UNIT_NAME = UNIT_KEYS[UNIT_KEYS.length - 1];
|
|
1007
|
+
const TIME_DICTIONARY_EN = {
|
|
1008
|
+
year: { long: "year", plural: "years", short: "y" },
|
|
1009
|
+
month: { long: "month", plural: "months", short: "m" },
|
|
1010
|
+
week: { long: "week", plural: "weeks", short: "w" },
|
|
1011
|
+
day: { long: "day", plural: "days", short: "d" },
|
|
1012
|
+
hour: { long: "hour", plural: "hours", short: "h" },
|
|
1013
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
1014
|
+
second: { long: "second", plural: "seconds", short: "s" },
|
|
1015
|
+
joinDuration: (primary, remaining) => `${primary} and ${remaining}`,
|
|
1016
|
+
};
|
|
1017
|
+
const TIME_DICTIONARY_FR = {
|
|
1018
|
+
year: { long: "an", plural: "ans", short: "a" },
|
|
1019
|
+
month: { long: "mois", plural: "mois", short: "m" },
|
|
1020
|
+
week: { long: "semaine", plural: "semaines", short: "s" },
|
|
1021
|
+
day: { long: "jour", plural: "jours", short: "j" },
|
|
1022
|
+
hour: { long: "heure", plural: "heures", short: "h" },
|
|
1023
|
+
minute: { long: "minute", plural: "minutes", short: "m" },
|
|
1024
|
+
second: { long: "seconde", plural: "secondes", short: "s" },
|
|
1025
|
+
joinDuration: (primary, remaining) => `${primary} et ${remaining}`,
|
|
1026
|
+
};
|
|
1027
|
+
|
|
1028
|
+
const humanizeEllapsedTime = (
|
|
1029
|
+
ms,
|
|
1030
|
+
{
|
|
1031
|
+
short,
|
|
1032
|
+
lang = "en",
|
|
1033
|
+
timeDictionnary = lang === "fr" ? TIME_DICTIONARY_FR : TIME_DICTIONARY_EN,
|
|
1034
|
+
} = {},
|
|
1035
|
+
) => {
|
|
997
1036
|
if (ms < 1000) {
|
|
998
|
-
return short
|
|
1037
|
+
return short
|
|
1038
|
+
? `0${timeDictionnary.second.short}`
|
|
1039
|
+
: `0 ${timeDictionnary.second.long}`;
|
|
999
1040
|
}
|
|
1000
1041
|
const { primary, remaining } = parseMs(ms);
|
|
1001
1042
|
if (!remaining) {
|
|
1002
|
-
return inspectEllapsedUnit(primary, short);
|
|
1043
|
+
return inspectEllapsedUnit(primary, { short, timeDictionnary });
|
|
1003
1044
|
}
|
|
1004
|
-
|
|
1005
|
-
remaining,
|
|
1045
|
+
const primaryText = inspectEllapsedUnit(primary, {
|
|
1006
1046
|
short,
|
|
1007
|
-
|
|
1047
|
+
timeDictionnary,
|
|
1048
|
+
});
|
|
1049
|
+
const remainingText = inspectEllapsedUnit(remaining, {
|
|
1050
|
+
short,
|
|
1051
|
+
timeDictionnary,
|
|
1052
|
+
});
|
|
1053
|
+
return timeDictionnary.joinDuration(primaryText, remainingText);
|
|
1008
1054
|
};
|
|
1009
|
-
const inspectEllapsedUnit = (unit, short) => {
|
|
1055
|
+
const inspectEllapsedUnit = (unit, { short, timeDictionnary }) => {
|
|
1010
1056
|
const count =
|
|
1011
1057
|
unit.name === "second" ? Math.floor(unit.count) : Math.round(unit.count);
|
|
1012
|
-
|
|
1058
|
+
const name = unit.name;
|
|
1013
1059
|
if (short) {
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
return `${count}${name}`;
|
|
1017
|
-
}
|
|
1018
|
-
return `${count}${name}s`;
|
|
1060
|
+
const unitText = timeDictionnary[name].short;
|
|
1061
|
+
return `${count}${unitText}`;
|
|
1019
1062
|
}
|
|
1020
1063
|
if (count <= 1) {
|
|
1021
|
-
|
|
1064
|
+
const unitText = timeDictionnary[name].long;
|
|
1065
|
+
return `${count} ${unitText}`;
|
|
1022
1066
|
}
|
|
1023
|
-
|
|
1024
|
-
}
|
|
1025
|
-
const unitShort = {
|
|
1026
|
-
year: "y",
|
|
1027
|
-
month: "m",
|
|
1028
|
-
week: "w",
|
|
1029
|
-
day: "d",
|
|
1030
|
-
hour: "h",
|
|
1031
|
-
minute: "m",
|
|
1032
|
-
second: "s",
|
|
1067
|
+
const unitText = timeDictionnary[name].plural;
|
|
1068
|
+
return `${count} ${unitText}`;
|
|
1033
1069
|
};
|
|
1034
1070
|
|
|
1035
1071
|
const humanizeDuration = (
|
|
1036
1072
|
ms,
|
|
1037
|
-
{
|
|
1073
|
+
{
|
|
1074
|
+
short,
|
|
1075
|
+
rounded = true,
|
|
1076
|
+
decimals,
|
|
1077
|
+
lang = "en",
|
|
1078
|
+
timeDictionnary = lang === "fr" ? TIME_DICTIONARY_FR : TIME_DICTIONARY_EN,
|
|
1079
|
+
} = {},
|
|
1038
1080
|
) => {
|
|
1039
1081
|
// ignore ms below meaningfulMs so that:
|
|
1040
1082
|
// humanizeDuration(0.5) -> "0 second"
|
|
@@ -1044,7 +1086,9 @@ const humanizeDuration = (
|
|
|
1044
1086
|
// yes we could return "0.1 millisecond" but we choosed consistency over precision
|
|
1045
1087
|
// so that the prefered unit is "second" (and does not become millisecond when ms is super small)
|
|
1046
1088
|
if (ms < 1) {
|
|
1047
|
-
return short
|
|
1089
|
+
return short
|
|
1090
|
+
? `0${timeDictionnary.second.short}`
|
|
1091
|
+
: `0 ${timeDictionnary.second.long}`;
|
|
1048
1092
|
}
|
|
1049
1093
|
const { primary, remaining } = parseMs(ms);
|
|
1050
1094
|
if (!remaining) {
|
|
@@ -1053,52 +1097,51 @@ const humanizeDuration = (
|
|
|
1053
1097
|
decimals === undefined ? (primary.name === "second" ? 1 : 0) : decimals,
|
|
1054
1098
|
short,
|
|
1055
1099
|
rounded,
|
|
1100
|
+
timeDictionnary,
|
|
1056
1101
|
});
|
|
1057
1102
|
}
|
|
1058
|
-
|
|
1103
|
+
const primaryText = humanizeDurationUnit(primary, {
|
|
1059
1104
|
decimals: decimals === undefined ? 0 : decimals,
|
|
1060
1105
|
short,
|
|
1061
1106
|
rounded,
|
|
1062
|
-
|
|
1107
|
+
timeDictionnary,
|
|
1108
|
+
});
|
|
1109
|
+
const remainingText = humanizeDurationUnit(remaining, {
|
|
1063
1110
|
decimals: decimals === undefined ? 0 : decimals,
|
|
1064
1111
|
short,
|
|
1065
1112
|
rounded,
|
|
1066
|
-
|
|
1113
|
+
timeDictionnary,
|
|
1114
|
+
});
|
|
1115
|
+
return timeDictionnary.joinDuration(primaryText, remainingText);
|
|
1067
1116
|
};
|
|
1068
|
-
const humanizeDurationUnit = (
|
|
1117
|
+
const humanizeDurationUnit = (
|
|
1118
|
+
unit,
|
|
1119
|
+
{ decimals, short, rounded, timeDictionnary },
|
|
1120
|
+
) => {
|
|
1069
1121
|
const count = rounded
|
|
1070
1122
|
? setRoundedPrecision(unit.count, { decimals })
|
|
1071
1123
|
: setPrecision(unit.count, { decimals });
|
|
1072
|
-
|
|
1124
|
+
const name = unit.name;
|
|
1073
1125
|
if (short) {
|
|
1074
|
-
|
|
1075
|
-
return `${count}${
|
|
1126
|
+
const unitText = timeDictionnary[name].short;
|
|
1127
|
+
return `${count}${unitText}`;
|
|
1076
1128
|
}
|
|
1077
1129
|
if (count <= 1) {
|
|
1078
|
-
|
|
1130
|
+
const unitText = timeDictionnary[name].long;
|
|
1131
|
+
return `${count} ${unitText}`;
|
|
1079
1132
|
}
|
|
1080
|
-
|
|
1081
|
-
}
|
|
1082
|
-
const MS_PER_UNITS = {
|
|
1083
|
-
year: 31_557_600_000,
|
|
1084
|
-
month: 2_629_000_000,
|
|
1085
|
-
week: 604_800_000,
|
|
1086
|
-
day: 86_400_000,
|
|
1087
|
-
hour: 3_600_000,
|
|
1088
|
-
minute: 60_000,
|
|
1089
|
-
second: 1000,
|
|
1133
|
+
const unitText = timeDictionnary[name].plural;
|
|
1134
|
+
return `${count} ${unitText}`;
|
|
1090
1135
|
};
|
|
1091
1136
|
|
|
1092
1137
|
const parseMs = (ms) => {
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
const firstUnitIndex = unitNames.findIndex((unitName) => {
|
|
1098
|
-
if (unitName === smallestUnitName) {
|
|
1138
|
+
let firstUnitName = SMALLEST_UNIT_NAME;
|
|
1139
|
+
let firstUnitCount = ms / UNIT_MS[SMALLEST_UNIT_NAME];
|
|
1140
|
+
const firstUnitIndex = UNIT_KEYS.findIndex((unitName) => {
|
|
1141
|
+
if (unitName === SMALLEST_UNIT_NAME) {
|
|
1099
1142
|
return false;
|
|
1100
1143
|
}
|
|
1101
|
-
const msPerUnit =
|
|
1144
|
+
const msPerUnit = UNIT_MS[unitName];
|
|
1102
1145
|
const unitCount = Math.floor(ms / msPerUnit);
|
|
1103
1146
|
if (unitCount) {
|
|
1104
1147
|
firstUnitName = unitName;
|
|
@@ -1107,7 +1150,7 @@ const parseMs = (ms) => {
|
|
|
1107
1150
|
}
|
|
1108
1151
|
return false;
|
|
1109
1152
|
});
|
|
1110
|
-
if (firstUnitName ===
|
|
1153
|
+
if (firstUnitName === SMALLEST_UNIT_NAME) {
|
|
1111
1154
|
return {
|
|
1112
1155
|
primary: {
|
|
1113
1156
|
name: firstUnitName,
|
|
@@ -1115,9 +1158,9 @@ const parseMs = (ms) => {
|
|
|
1115
1158
|
},
|
|
1116
1159
|
};
|
|
1117
1160
|
}
|
|
1118
|
-
const remainingMs = ms - firstUnitCount *
|
|
1119
|
-
const remainingUnitName =
|
|
1120
|
-
const remainingUnitCount = remainingMs /
|
|
1161
|
+
const remainingMs = ms - firstUnitCount * UNIT_MS[firstUnitName];
|
|
1162
|
+
const remainingUnitName = UNIT_KEYS[firstUnitIndex + 1];
|
|
1163
|
+
const remainingUnitCount = remainingMs / UNIT_MS[remainingUnitName];
|
|
1121
1164
|
// - 1 year and 1 second is too much information
|
|
1122
1165
|
// so we don't check the remaining units
|
|
1123
1166
|
// - 1 year and 0.0001 week is awful
|