interface INumberConversionItem<K> {
unit: K; // 单位
carry: number; // 进制
}
interface INumberConversionOpts<K> {
items: INumberConversionItem<K>[];
parseFunc: (data: INumberConversionItem<K> & { index: number; value: number }) => string;
minUnit?: K; // 最小单位
}
function createNumberConversion<K>(opts: INumberConversionOpts<K>) {
const { items, parseFunc, minUnit } = opts;
return (data: number) => {
let index = 0;
let value = data;
while (index < items.length - 1 && value >= items[index].carry) {
value /= items[index].carry;
index++;
}
const minIndex = minUnit ? items.findIndex(item => item.unit === minUnit) : -1;
if (minIndex !== -1) {
while (index < minIndex) {
value /= items[index].carry;
index++;
}
}
return parseFunc({ ...items[index], index, value });
};
}
// ----------------------------
const sizeUnits = ['B', 'K', 'M', 'G', 'T'] as const;
const formatSizeNumber = createNumberConversion({
items: sizeUnits.map(unit => ({ unit, carry: 1024 })),
parseFunc: ({ unit, value }) => `${value.toFixed(0)}${unit}`,
});
[
'1',
'1024',
'1024 * 1024',
'1024 * 1024 * 1024',
'1024 * 1024 * 1024 * 1024',
'1024 * 1024 * 1024 * 1024 * 99999',
].forEach(item => {
console.log(`${formatSizeNumber(eval(item))}: ${item}`);
});
// 1B: 1
// 1K: 1024
// 1M: 1024 * 1024
// 1G: 1024 * 1024 * 1024
// 1T: 1024 * 1024 * 1024 * 1024
// 99999T: 1024 * 1024 * 1024 * 1024 * 99999
// ----------------------------
const formatTimeNumber = createNumberConversion({
items: [
{ unit: '秒', carry: 60 },
{ unit: '分钟', carry: 60 },
{ unit: '小时', carry: 24 },
{ unit: '天', carry: 30 },
{ unit: '个月', carry: 12 },
{ unit: '年', carry: Infinity },
] as const,
parseFunc: ({ unit, value }) => `${value.toFixed(0)}${unit}`,
});
[
'1',
'60',
'60 * 60',
'60 * 60 * 24',
'60 * 60 * 24 * 30',
'60 * 60 * 24 * 30 * 12',
'60 * 60 * 24 * 30 * 12 * 1000',
].forEach(item => {
console.log(`${formatTimeNumber(eval(item))}: ${item}`);
});
// 1秒: 1
// 1分钟: 60
// 1小时: 60 * 60
// 1天: 60 * 60 * 24
// 1个月: 60 * 60 * 24 * 30
// 1年: 60 * 60 * 24 * 30 * 12
// 1000年: 60 * 60 * 24 * 30 * 12 * 1000