Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Seconds Formatting Function #74

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/pages/function/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"not": "not",
"sleep": "sleep",
"throttle": "throttle",
"try-or": "tryOr"
"try-or": "tryOr",
"format-seconds": "format-seconds"
}
70 changes: 70 additions & 0 deletions docs/pages/function/format-seconds.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@

# formatSeconds

The `formatSeconds` function is designed to convert a given number of seconds into a human-readable time string.
By accepting a specified format, this function allows for flexible output options, such as displaying time in hours, minutes, and seconds, or just in minutes and seconds. Whether you need to present durations in a detailed format like `hh:mm:ss` or a more concise `mm:ss`, this function caters to various use cases in applications that require time representation.


### Import

```typescript
import { formatSeconds } from '@fullstacksjs/toolbox';
```

### Signature

```typescript
function formatSeconds(
durationInSeconds: number,
options
): string;
```

## Parameters

- **`durationInSeconds`** (`number`): The total number of seconds to be converted.
- **`options`** (`{ format: 'hh:mm:ss' | 'hh:mm' | 'mm:ss' }`): The desired output format.

## Returns

- **`string`**: The formatted time string based on the specified format.

## Examples

### Formatting to `hh:mm:ss`

```typescript
const time1 = formatSeconds(3661, { format: 'hh:mm:ss' });
// Output: '01:01:01'
```

### Formatting to `hh:mm`

```typescript
const time2 = formatSeconds(3661, { format: 'hh:mm' });
// Output: '01:01'
```

### Formatting to `mm:ss`

```typescript
const time3 = formatSeconds(61, { format: 'mm:ss' });
// Output: '01:01'
```

### Formatting Zero Seconds

```typescript
const time4 = formatSeconds(0, { format: 'mm:ss' });
// Output: '00:00'
```

## Error Handling

If an invalid format is provided, the function will throw an error:

```typescript
formatSeconds(120, { format: 'ss:ss:ss' });
// 'Invalid format: 'ss:ss:ss'. Accepted formats are 'hh:mm:ss', 'hh:mm', or 'mm:ss'.'
```

29 changes: 29 additions & 0 deletions src/function/formatSeconds.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { formatSeconds } from './formatSeconds.ts';

describe('secondToTime', () => {
it('should return zero when pass 0 seconds', () => {
const format = 'mm:ss';
const sec = 0;

expect(formatSeconds(sec, { format })).toBe('00:00');
});

it.todo('should throw an error when pass invalid format', () => {
const inValidFormat = 'ss:ss:ss';
const sec = 120;

// @ts-expect-error : not assignable type, ignored in order to have a test
expect(formatSeconds({ sec, format: inValidFormat })).toThrow();
});

it.each([
[3661, { format: 'hh:mm:ss' as const }, '01:01:01'],
[3661, { format: 'hh:mm' as const }, '01:01'],
[61, { format: 'mm:ss' as const }, '01:01'],
])(
'should format seconds to %s for input %o',
(durationInSeconds, options, expected) => {
expect(formatSeconds(durationInSeconds, options)).toBe(expected);
},
);
});
67 changes: 67 additions & 0 deletions src/function/formatSeconds.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* Pads a number with leading zeros.
*
* @param {number} value - The number to pad.
* @returns {string} - The padded number as a string.
*/

function formatToTwoDigits(value: number): string {
return String(value).padStart(2, '0');
}

/**
* Splits a duration in seconds into hours, minutes, and seconds.
*
* @param {number} durationInSeconds - The total seconds.
* @returns {{ hours: number, minutes: number, seconds: number }} - The time components.
*/

function splitTime(durationInSeconds: number): {
hours: number;
minutes: number;
seconds: number;
} {
return {
hours: Math.trunc(durationInSeconds / 3600),
minutes: Math.trunc((durationInSeconds % 3600) / 60),
seconds: durationInSeconds % 60,
};
}

/**
* Formats seconds into the specified time format.
*
* @param {number} durationInSeconds - The total number of seconds to be converted.
* @param {{ format: 'hh:mm:ss' | 'hh:mm' | 'mm:ss' }} options - The options for formatting.
* @returns {string} - The formatted time string.
*
* @example
*
* formatSeconds(3661, { format: 'hh:mm:ss' }) // '01:01:01'
* formatSeconds(3661, { format: 'hh:mm' }) // '01:01'
* formatSeconds(61, { format: 'mm:ss' }) // '01:01'
*/

export function formatSeconds(
durationInSeconds: number,
{
format,
}: {
format: 'hh:mm:ss' | 'hh:mm' | 'mm:ss';
},
): number | string {
const { hours, minutes, seconds } = splitTime(durationInSeconds);

switch (format) {
case 'hh:mm:ss':
return `${formatToTwoDigits(hours)}:${formatToTwoDigits(minutes)}:${formatToTwoDigits(seconds)}`;
case 'hh:mm':
return `${formatToTwoDigits(hours)}:${formatToTwoDigits(minutes)}`;
case 'mm:ss':
return `${formatToTwoDigits(minutes)}:${formatToTwoDigits(seconds)}`;
default:
throw new Error(
`Invalid format: '${format as string}'. Accepted formats are 'hh:mm:ss', 'hh:mm', or 'mm:ss'.`,
);
}
}