Skip to content

Commit 79d22b9

Browse files
committed
feat: support custom time units
1 parent 972b3eb commit 79d22b9

3 files changed

Lines changed: 134 additions & 55 deletions

File tree

docs/api/functions/formatSecond.md

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,69 @@
22

33
# Function: formatSecond()
44

5-
> **formatSecond**(`secondTime`, `padZero`): `string`
5+
> **formatSecond**(`secondTime`, `options?`): `string`
66
7-
Defined in: [formatSecond/index.ts:34](https://github.com/DTStack/dt-utils/blob/master/src/formatSecond/index.ts#L34)
7+
Defined in: [formatSecond/index.ts:75](https://github.com/DTStack/dt-utils/blob/master/src/formatSecond/index.ts#L75)
88

9-
将秒数转换为时间格式 (HH[h]mm[m]ss[s])
9+
将秒数格式化为可读的时间字符串。
10+
11+
支持:
12+
- 自定义时间单位(h / m / s)
13+
- 数值补零(padZero)
14+
- 通过 format 模板输出(如 HH:mm:ss
1015

1116
## Parameters
1217

1318
### secondTime
1419

1520
`number` = `0`
1621

17-
需要转换的秒数
22+
需要转换的秒数(小于等于 0、NaN、非数字将视为 0)
1823

19-
### padZero
24+
### options?
2025

21-
`boolean` = `false`
26+
`FormatSecondOptions` = `{}`
2227

23-
是否使用 HH[h]mm[m]ss[s] 格式
28+
格式化选项
2429

2530
## Returns
2631

2732
`string`
2833

29-
格式化后的时间字符串,包含小时(h)、分钟(m)和秒(s)
34+
格式化后的时间字符串
3035

3136
## Example
3237

33-
```typescript
38+
```ts
3439
import { formatSecond } from 'dt-utils';
3540

36-
// 基本用法
37-
formatSecond(3661) // => '1h1m1s'
38-
formatSecond(59) // => '59s'
39-
formatSecond(0) // => '0s'
41+
// 基本用法(默认单位:h / m / s)
42+
formatSecond(3661) // => '1h1m1s'
43+
44+
formatSecond(59) // => '59s'
45+
46+
formatSecond(0) // => '0s'
47+
48+
// 补零
49+
formatSecond(3661, { padZero: true }) // => '01h01m01s'
50+
51+
formatSecond(60, { padZero: true }) // => '01m'
52+
53+
// 自定义单位(中文)
54+
formatSecond(1106, {
55+
units: { h: '小时', m: '', s: '' },
56+
}) // => '18分26秒'
57+
58+
// 使用 format 模板(运行时长)
59+
formatSecond(12078, {
60+
format: 'HH:mm:ss',
61+
padZero: true,
62+
}) // => '03:21:18'
4063

41-
// 处理大数字
42-
formatSecond(7323) // => '2h2m3s'
43-
formatSecond(3600) // => '1h'
64+
// 边界情况
65+
formatSecond(-1) // => '0s'
4466

45-
// 处理边界情况
46-
formatSecond(-1) // => '0s'
47-
formatSecond(NaN) // => '0s'
48-
formatSecond() // => '0s'
67+
formatSecond(NaN) // => '0s'
4968

50-
// 使用 HH[h]mm[m]ss[s] 格式
51-
formatSecond(3661) // => '01h01m01s'
52-
formatSecond(60) // => '01m'
53-
formatSecond(0) // => '00s'
69+
formatSecond() // => '0s'
5470
```

src/formatSecond/__test__/index.test.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,30 @@ describe('formatSecond', () => {
6262
});
6363

6464
// Test padZero
65-
test('should correctly format time with zero-padded hours, minutes and seconds', () => {
66-
expect(formatSecond(3661, true)).toBe('01h01m01s');
67-
expect(formatSecond(3600, true)).toBe('01h');
68-
expect(formatSecond(60, true)).toBe('01m');
69-
expect(formatSecond(1, true)).toBe('01s');
70-
expect(formatSecond(0, true)).toBe('00s');
65+
test('pads hour, minute and second with zero', () => {
66+
expect(formatSecond(3661, { padZero: true })).toBe('01h01m01s');
67+
expect(formatSecond(60, { padZero: true })).toBe('01m');
68+
expect(formatSecond(5, { padZero: true })).toBe('05s');
69+
});
70+
71+
test('pads zero second correctly', () => {
72+
expect(formatSecond(0, { padZero: true })).toBe('00s');
73+
});
74+
75+
// Custom units
76+
test('supports chinese units', () => {
77+
expect(
78+
formatSecond(1106, {
79+
units: { h: '小时', m: '分', s: '秒' },
80+
})
81+
).toBe('18分26秒');
82+
});
83+
84+
test('supports partial units override', () => {
85+
expect(
86+
formatSecond(61, {
87+
units: { m: 'min', s: 'sec' },
88+
})
89+
).toBe('1min1sec');
7190
});
7291
});

src/formatSecond/index.ts

Lines changed: 69 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,82 @@
1+
type TimeUnit = 'h' | 'm' | 's';
2+
3+
interface FormatSecondOptions {
4+
/** 单位文案映射 */
5+
units?: Partial<Record<TimeUnit, string>>;
6+
/** 是否补零 */
7+
padZero?: boolean;
8+
}
9+
110
/**
2-
* 将秒数转换为时间格式 (HH[h]mm[m]ss[s])
11+
* 将秒数格式化为可读的时间字符串。
12+
*
13+
* 支持:
14+
* - 自定义时间单位(h / m / s)
15+
* - 数值补零(padZero)
16+
* - 通过 format 模板输出(如 HH:mm:ss)
317
*
418
* @category 格式化
519
*
6-
* @param {number} secondTime - 需要转换的秒数
7-
* @param {boolean} padZero - 是否使用 HH[h]mm[m]ss[s] 格式
8-
* @returns {string} 格式化后的时间字符串,包含小时(h)、分钟(m)和秒(s)
20+
* @param {number} secondTime
21+
* 需要转换的秒数(小于等于 0、NaN、非数字将视为 0)
22+
*
23+
* @param {Object} [options]
24+
* 格式化选项
25+
*
26+
* @param {boolean} [options.padZero=false]
27+
* 是否对小时、分钟、秒进行补零(如 02h、03m、09s)
28+
*
29+
* @param {Object} [options.units]
30+
* 时间单位映射,可自定义 h / m / s 的展示文案
31+
*
32+
* @param {string} [options.format]
33+
* 格式化模板,支持 HH、mm、ss(如 HH:mm:ss)
34+
* 若传入 format,则优先使用模板输出
35+
*
36+
* @returns {string}
37+
* 格式化后的时间字符串
938
*
1039
* @example
11-
* ```typescript
40+
* ```ts
1241
* import { formatSecond } from 'dt-utils';
1342
*
14-
* // 基本用法
15-
* formatSecond(3661) // => '1h1m1s'
16-
* formatSecond(59) // => '59s'
17-
* formatSecond(0) // => '0s'
43+
* // 基本用法(默认单位:h / m / s)
44+
* formatSecond(3661) // => '1h1m1s'
45+
*
1846
*
19-
* // 处理大数字
20-
* formatSecond(7323) // => '2h2m3s'
21-
* formatSecond(3600) // => '1h'
47+
* formatSecond(59) // => '59s'
2248
*
23-
* // 处理边界情况
24-
* formatSecond(-1) // => '0s'
25-
* formatSecond(NaN) // => '0s'
26-
* formatSecond() // => '0s'
49+
* formatSecond(0) // => '0s'
2750
*
28-
* // 使用 HH[h]mm[m]ss[s] 格式
29-
* formatSecond(3661) // => '01h01m01s'
30-
* formatSecond(60) // => '01m'
31-
* formatSecond(0) // => '00s'
51+
* // 补零
52+
* formatSecond(3661, { padZero: true }) // => '01h01m01s'
53+
*
54+
* formatSecond(60, { padZero: true }) // => '01m'
55+
*
56+
* // 自定义单位(中文)
57+
* formatSecond(1106, {
58+
* units: { h: '小时', m: '分', s: '秒' },
59+
* }) // => '18分26秒'
60+
*
61+
* // 使用 format 模板(运行时长)
62+
* formatSecond(12078, {
63+
* format: 'HH:mm:ss',
64+
* padZero: true,
65+
* }) // => '03:21:18'
66+
*
67+
* // 边界情况
68+
* formatSecond(-1) // => '0s'
69+
*
70+
* formatSecond(NaN) // => '0s'
71+
*
72+
* formatSecond() // => '0s'
3273
* ```
3374
*/
34-
export const formatSecond = (secondTime = 0, padZero = false): string => {
75+
export const formatSecond = (secondTime = 0, options: FormatSecondOptions = {}): string => {
76+
const { units = { h: 'h', m: 'm', s: 's' }, padZero = false } = options;
77+
3578
if (typeof secondTime !== 'number' || isNaN(secondTime) || secondTime <= 0) {
36-
return padZero ? '00s' : '0s';
79+
return padZero ? `00${units.s}` : `0${units.s}`;
3780
}
3881

3982
const totalSeconds = Math.floor(secondTime);
@@ -44,10 +87,11 @@ export const formatSecond = (secondTime = 0, padZero = false): string => {
4487
const pad = (num: number) => (padZero ? String(num).padStart(2, '0') : String(num));
4588

4689
const parts: string[] = [];
47-
if (hours > 0) parts.push(`${pad(hours)}h`);
48-
if (minutes > 0) parts.push(`${pad(minutes)}m`);
49-
if (seconds > 0 || parts.length === 0) parts.push(`${pad(seconds)}s`);
90+
if (hours > 0) parts.push(`${pad(hours)}${units.h}`);
91+
if (minutes > 0) parts.push(`${pad(minutes)}${units.m}`);
92+
if (seconds > 0 || parts.length === 0) parts.push(`${pad(seconds)}${units.s}`);
5093

5194
return parts.join('');
5295
};
96+
5397
export default formatSecond;

0 commit comments

Comments
 (0)