Skip to content
Merged

V2 #5

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
74 changes: 46 additions & 28 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,54 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Breaking

- Renames `toParts` to `msToParts`
- Renames `MICROSECONDS_IN_A_MILLISECOND` to `MICROSECONDS_IN_MILLISECOND`
- Renames `MILLISECONDS_IN_A_SECOND` to `MILLISECONDS_IN_SECOND`
- Renames `NANOSECONDS_IN_A_MICROSECOND` to `NANOSECONDS_IN_MICROSECOND`

### Added

- `msToClock` function to convert milliseconds to a clock string
- `clockToMs` function to convert a clock string to milliseconds
- `partsToMs` function to convert an object with time unit properties to milliseconds
- `Parts` interface to represent the parts of a duration
- `TimeUnit` type to represent the time unit strings used in the `parseDuration` function

### Fixed

- Incorrect/missing documentation
- Floating point conversion error

## [1.2.0] - 2025-06-10

### Added

- Code coverage check (thanks [@simmo])
- Microseconds and nanoseconds support (thanks [@simmo])
- Code coverage check
- Microseconds and nanoseconds support

## [1.1.2] - 2025-05-06

### Changes
### Changed

- Workflow adjustments (thanks [@simmo])
- Workflow adjustments

### Fixed

- Missing package files path (thanks [@simmo])
- Missing package files path

## [1.1.1] - 2025-05-05

### Added

- Contributing guide (thanks [@simmo])
- Security policy (thanks [@simmo])
- PR + issue templates (thanks [@simmo])
- Contributing guide
- Security policy
- PR + issue templates

### Changed

- README adjustments (thanks [@simmo])
- README adjustments

### Fixed

Expand All @@ -44,53 +64,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `weeks` unit converter (thanks [@simmo])
- `WEEK` and `DAYS_IN_WEEK` constants (thanks [@simmo])
- `weeks` to `toParts` function output (thanks [@simmo])
- `weeks` unit converter
- `WEEK` and `DAYS_IN_WEEK` constants
- `weeks` to `toParts` function output

### Changed

- Updated dev dependencies (thanks [@simmo])
- Output modules in distribution (thanks [@simmo])
- Updated dev dependencies
- Output modules in distribution

### Fixes

- README typos (thanks [@simmo])
- Clean up (thanks [@simmo])
- Changelog URLs (thanks [@simmo])
- README typos
- Clean up
- Changelog URLs

## [1.0.0] - 2025-05-05

### Changed

- Update readme (thanks [@simmo])
- Update readme

## [0.0.2] - 2025-05-05

### Fixed

- Update incorrect documentation (thanks [@simmo])
- Update README (thanks [@simmo])
- Update incorrect documentation
- Update README

## [0.0.1] - 2025-05-04

### Added

- Initial setup (thanks [@simmo])
- Constants for time units (thanks [@simmo])
- Unit converter functions for `days`, `hours`, `minutes`, `seconds` and `milliseconds` (thanks [@simmo])
- `toParts` function to convert milliseconds to an object with properties for each time unit (thanks [@simmo])
- `parseDuration` function to parse a duration string into milliseconds (thanks [@simmo])
- Initial setup
- Constants for time units
- Unit converter functions for `days`, `hours`, `minutes`, `seconds` and `milliseconds`
- `toParts` function to convert milliseconds to an object with properties for each time unit
- `parseDuration` function to parse a duration string into milliseconds

[#3]: https://github.com/simmo/niobe/pull/3
[@spyros-uk]: https://github.com/spyros-uk
[unreleased]: https://github.com/simmo/niobe/compare/1.2.0...HEAD
[1.0.0]: https://github.com/simmo/niobe/compare/0.0.2...1.0.0
[0.0.2]: https://github.com/simmo/niobe/compare/0.0.1...0.0.2
[0.0.1]: https://github.com/simmo/niobe/compare/f3751e...0.0.1
[1.1.0]: https://github.com/simmo/niobe/compare/1.0.1-beta.1...1.1.0
[@simmo]: https://github.com/simmo
[@spyros-uk]: https://github.com/spyros-uk
[1.1.1]: https://github.com/simmo/niobe/compare/1.1.1-beta.2...1.1.1
[1.1.2]: https://github.com/simmo/niobe/compare/1.1.2-beta.0...1.1.2

[1.2.0]: https://github.com/simmo/niobe/releases/tag/1.2.0
76 changes: 74 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ setTimeout(() => /* Do something */}, minutes(2) + seconds(30));

Additionally, Niobe provides [utilities](#utilities) to parse durations, split them into their components and [convert](#conversion) between different time units. There is even a range of common [constants](#constants).

Take a look at the [FAQs](#faqs) for more information, the [CHANGELOG](./CHANGELOG.md) for the latest changes or the [contribution guide](./CONTRIBUTING.md) if you want to get involved.

---

## Installation
Expand Down Expand Up @@ -99,6 +101,25 @@ _[This seems pointless, why is it here?](#this-seems-pointless-why-is-it-here)_

### Utilities

#### `clockToMs(clock: string): number`

Converts a `hh:mm:ss.ms_μs_ns` string to milliseconds.

- `hh` - Hours - Optional, optional leading zero
- `mm` - Minutes - Optional, optional leading zero
- `ss` - Seconds - Required, optional leading zero
- `ms` - Milliseconds - Optional, optional trailing zeros
- `μs` - Microseconds - Optional, optional trailing zeros
- `ns` - Nanoseconds - Optional, optional trailing zeros

Milliseconds, microseconds, and nanoseconds can be optionally separated by underscores, if not, you must provide padding.

#### `msToClock(milliseconds: number, options?: { separateDecimal = true }): string`

Converts milliseconds to a string in the format 'hh:mm:ss' optionally suffixing '.ms_μs_ns' if there are any remaining milliseconds, microseconds or nanoseconds.

`separateDecimal` - If true, milliseconds, microseconds, and nanoseconds will be separated by underscores. If false, they will be concatenated without separators.

#### `parseDuration(duration: string, strict: boolean = false): number`

Parses a duration string, returning milliseconds.
Expand All @@ -113,6 +134,9 @@ parseDuration('2m 1s');

parseDuration('1h 2m 3s');
// => 3_723_004

parseDuration('1d 2h 3m 4s 5ms 6μs 7ns');
// => 93_784_005.006_007
```

###### Invalid format - Non-strict (Default)
Expand All @@ -132,14 +156,54 @@ parseDuration('invalid', true);
// => throws Error: "invalid" is not a valid duration
```

#### `toParts(milliseconds: number): { days: number, hours: number, minutes: number, seconds: number, milliseconds: number }`
#### `msToParts(milliseconds: number): Parts`

Converts a duration in milliseconds to a [Parts](#parts) object with properties for each time unit.

#### `partsToMs(parts: Partial<Parts>): number`

Converts a [Parts](#parts) object to duration in milliseconds.

### Types

#### `TimeUnit`

This type represents the time unit strings used in the [`parseDuration`](#parsedurationduration-string-strict-boolean--false-number) function. It can be one of the following:

```ts
type TimeUnit = 'ns' | 'μs' | 'ms' | 's' | 'm' | 'h' | 'd' | 'w';
```

#### `Parts`

Converts a duration in milliseconds to an object with properties for each time unit.
Used in the [`msToParts`](#mstopartsmilliseconds-number-parts) and [`partsToMs`](#partstomsparts-partialparts-number) functions. This interface represents the parts of a duration.

```ts
interface Parts {
days: number;
hours: number;
isNegative: boolean;
nanoseconds: number;
microseconds: number;
milliseconds: number;
minutes: number;
seconds: number;
weeks: number;
}
```

### Constants

These constants are used to represent the number of milliseconds in each time unit.

#### `NANOSECOND`

One nanosecond in milliseconds.

#### `MICROSECOND`

One microsecond in milliseconds.

#### `MILLISECOND`

One millisecond.
Expand All @@ -166,6 +230,14 @@ One day in milliseconds.

One week in milliseconds.

#### `NANOSECONDS_IN_MICROSECOND`

Number of nanoseconds in a second.

#### `MICROSECONDS_IN_MILLISECOND`

Number of microseconds in a second.

#### `MILLISECONDS_IN_SECOND`

Number of milliseconds in a second.
Expand Down
59 changes: 59 additions & 0 deletions src/clockToMs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { describe, expect, it } from 'vitest';

import { clockToMs } from './clockToMs.js';

const testCases = [
[1_000, '00:00:01'],
[61_000, '00:01:01'],
[3_661_000, '01:01:01'],
[1_000, '1'],
[1_000, '01'],
[61_000, '1:1'],
[61_000, '1:01'],
[61_000, '01:1'],
[3_661_000, '1:1:1'],
[3_661_000, '1:1:01'],
[3_661_000, '1:01:01'],
[1_500.000_005, '00:00:01.500000005'],
[61_500.000_005, '00:01:01.500000005'],
[3_661_500.000_005, '01:01:01.500000005'],
[1_500.000_005, '1.500000005'],
[1_500.000_005, '01.500000005'],
[61_500.000_005, '1:1.500000005'],
[61_500.000_005, '1:01.500000005'],
[61_500.000_005, '01:1.500000005'],
[3_661_500.000_005, '1:1:1.500000005'],
[3_661_500.000_005, '1:1:01.500000005'],
[3_661_500.000_005, '1:01:01.500000005'],
[1_500.000_005, '00:00:01.500_000_005'],
[61_500.000_005, '00:01:01.500_000_005'],
[3_661_500.000_005, '01:01:01.500_000_005'],
[1_500.000_005, '1.500_000_005'],
[1_500.000_005, '01.500_000_005'],
[61_500.000_005, '1:1.500_000_005'],
[61_500.000_005, '1:01.500_000_005'],
[61_500.000_005, '01:1.500_000_005'],
[3_661_500.000_005, '1:1:1.500_000_005'],
[3_661_500.000_005, '1:1:01.500_000_005'],
[3_661_500.000_005, '1:01:01.500_000_005'],
[3_661_500.000_005, '1:01:01.500_000_005'],
[3_661_500.000_005, '1:01:01.5_0_005'],
[3_661_500.500_500, '1:01:01.5_5_5'],
[3_661_500.500_500, '01:01:01.500_500_500'],
] as const;

describe('clockToMs()', () => {
describe.each([
['positive', false],
['negative', true],
])('%s time', (_, isNegative) => {
const [offset, sign] = isNegative ? [-1, '-'] : [1, ''];

it.each(testCases)(
`returns ${sign}%s for ${sign}%s`,
(milliseconds, clock) => {
expect(clockToMs(`${sign}${clock}`)).toBe(milliseconds * offset);
},
);
});
});
Loading