@standards/duration
Version:
Human-readable, convenient, friendly durations. Converts durations given as strings to milliseconds or to custom units from milliseconds to weeks.
469 lines (378 loc) • 16.6 kB
Markdown
<!-- Logo -->
<p align="center">
<img src="https://cdn.jsdelivr.net/gh/js-standards/duration/assets/icontype.svg" alt="@standards/duration" />
</p>
<!-- Branded divider -->
<a href="https://github.com/js-standards"><img src="https://cdn.jsdelivr.net/npm/@standards/assets@1.0.2/brand/media/github/divider.svg" alt="divider" /></a>
<!-- Badges - 1st row -->
<p align="center">
<!-- NPM badge -->
<a href="https://www.npmjs.com/package/@standards/duration"><img src="https://img.shields.io/npm/v/@standards/duration?color=brightgreen&style=flat-square" alt="release-badge"></a>
<!-- CI badge -->
<a href="https://github.com/js-standards/duration/actions?query=workflow%3Aci"><img src="https://github.com/js-standards/duration/workflows/ci/badge.svg?style=flat-square" alt="ci-badge"></a>
<!-- Coverage badge -->
<a href="https://codecov.io/gh/js-standards/duration"><img src="https://img.shields.io/codecov/c/github/js-standards/duration?style=flat-square" alt="coverage-badge"></a>
<!-- Dependency badge -->
<a href="https://libraries.io/github/js-standards/duration"><img src="https://img.shields.io/badge/dependabot-enabled-brightgreen.svg?style=flat-square" alt="dependency-badge"></a>
<!-- Documentation badge -->
<a href="https://github.com/js-standards/duration/blob/master/docs/API.md"><img src="https://inch-ci.org/github/js-standards/duration.svg?branch=master&style=flat-square" alt="documentation-badge"></a>
</p>
<!-- Badges - 2nd row -->
<p align="center">
<!-- Code style badge -->
<a href="https://standardjs.com"><img src="https://img.shields.io/badge/style-standardjs-f1d300.svg?style=flat-square" alt="code-style-badge"></a>
<!-- Commit style badge -->
<a href="https://commitizen.github.io/cz-cli"><img src="https://img.shields.io/badge/commit-commitizen-fe7d37.svg?style=flat-square" alt="commit-style-badge"></a>
<!-- Release workflow badge -->
<a href="https://semantic-release.gitbook.io/semantic-release"><img src="https://img.shields.io/badge/release-semantic--release-e10079.svg?style=flat-square" alt="release-workflow-badge"></a>
<!-- License badge -->
<a href="https://github.com/js-standards/duration/blob/master/LICENSE.md"><img src="https://img.shields.io/badge/license-ISC-blue.svg?style=flat-square" alt="license-badge"></a>
<!-- Contribution badge -->
<a href="https://github.com/js-standards/duration/blob/master/.github/CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square" alt="contribution-badge"></a>
</p>
---
<h3 align="center">
Human-readable, convenient, friendly durations.
</h3>
<p align="center">
Converts durations given as <b>strings to milliseconds</b> or to custom units from milliseconds to weeks.
</p>
---
## :thinking: Why?
- **1.:** It's **more intuitive** for everyday use, when dealing with durations :heart::
```javascript
// general job cycle
const cycle = duration('36 hours') // === 129600000 in milliseconds
// movie playtime
const length = duration('2h 41m') // === 9660000 in milliseconds
// will log out "It is time!" in ~60,000 milliseconds
setTimeout(() => console.log('It is time!'), duration('1 min'))
// delays the execution for ~15,000 milliseconds
await delay(duration('15 seconds'))
```
- **2.:** It's easier, when **handling larger or more complex durations** :muscle::
```javascript
// custom notification set manually by a user
const notifyIn = duration('24 hours 36 minutes 49 seconds') // === 88609000
// cookie will expire in 7776000000 milliseconds from now
const date = new Date(Date.now() + duration('90 days'))
document.cookie = 'value=42;expires=' + date.toUTCString() + ';path=/')
// 24192000000 milliseconds from now
User.update(
{ logged_out_warn_time: Date.now() + duration('280 days'), },
{ where: { id } }
)
```
- **3.:** It's **highly configurable** and the inputs are **cached** :godmode::
```javascript
// custom return unit with a default fallback
duration('42 hours', '1 hour', { unit: 'seconds' }) // === 151200 in seconds
// create a custom duration function with predefined arguments
const custom = createCustom(0, '1 day', { unit: 'seconds' })
// will return the given duration in seconds ({ unit: 'seconds' })
custom('1 hour') // === 3600 in seconds
```
## :package: Installation
- **NPM:**
```bash
npm install @standards/duration
```
- **Yarn:**
```bash
yarn add @standards/duration
```
## :coffee: Usage
**@standards/duration** can be used in **Node.js**, in the **Browser**, and ***in every*** current module format, system, environment, and variety including **CommonJS**, **ESM**, **UMD**, **AMD**, **SystemJS** and [***more***][url-cdn].
- **CommonJS:**
```javascript
const duration = require('@standards/duration')
```
- **ES Module:**
```javascript
import duration from '@standards/duration'
```
- **In Browser**:
```html
<script src="https://cdn.jsdelivr.net/npm/@standards/duration/dist/duration.umd.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
console.log(duration('42 sec')) // === 42000
})
</script>
```
- **AMD, SystemJS, IIFE, and Others:**
Check out the [**additional variations and SRI hashes on jsDelivr CDN**][url-cdn].
### :satisfied: Usage - General
```javascript
// these will return milliseconds
duration('3.5h') // === 12600000
duration('1.5h') // === 5400000
duration('175min') // === 10500000
duration('300ms') // === 300
// singulars, plurals, and shorthands work as expected
duration('2s') // === 2000
duration('2sec') // === 2000
duration('2second') // === 2000
duration('2seconds') // === 2000
duration('2 second') // === 2000
duration('2 seconds') // === 2000
// whitespaces don't matter
duration('42 sec') // === 42000
duration(' 42sec') // === 42000
duration('42sec ') // === 42000
duration(' 42 sec ') // === 42000
// commas, underscores, and dashes are allowed
duration('10000 sec') // === 10000000
duration('10,000 sec') // === 10000000
duration('10_000 sec') // === 10000000
duration('10-000 sec') // === 10000000
// multiple units are allowed too, even the crazier ones
duration('1 hour 23 minutes 45 seconds 600 milliseconds') // === 5025600
duration('100ms 200ms') // === 300
duration('500ms 400ms 300ms 200ms 100ms') // === 1500
duration('1s 2sec 3secs 4second 5seconds') // === 15000
duration('1.1h 2.2h 3.3h 4.4h 5.5h') // === 59400000
duration('0.5d 1.0day 1.5day 2.0days') // === 432000000
```
### :yum: Usage - Custom Fallback
```javascript
// these will return the fallback duration
duration(undefined, '1 hour') // === 3600000
duration(null, '45 min') // === 2700000
duration(false, '60sec') // === 60000
```
### :heart_eyes: Usage - Custom Return Unit
```javascript
// 1 hour in seconds
duration('1 h', { unit: 's' }) // === 3600
// 2 days in minutes
duration('2 days', { unit: 'minutes' }) // === 2880
// 3 weeks, 5 days and 12 hours in hours
duration('3w 5days 12 h', { unit: 'h' }) // === 636
```
### :anguished: Usage - Custom Duration Function
```javascript
// ---------- in CommonJS --------------------
const duration = require('@standards/duration')
// custom duration function
// with 1 hour as a fallback, return unit is in seconds
const custom = duration.createCustom(null, '1 hour', { unit: 'sec' })
```
```javascript
// ---------- in ES Module ----------------------
import { createCustom } from '@standards/duration'
// custom duration function
// with 1 hour as a fallback, return unit is in seconds
const custom = createCustom(null, '1 hour', { unit: 'sec' })
```
```javascript
// will return the fallback, which is "1 hour" in seconds ({ unit: 'sec' })
custom() // === 3600
// will return 2 hours in seconds, since the return unit is "sec"
custom('2 hours') // === 7200
```
---
## :computer: API
<!--- <% API --->
<a name="module_@standards/duration"></a>
## @standards/duration
* [@standards/duration](#module_@standards/duration)
* [~duration([duration], [defaultOrOptions], [options])](#module_@standards/duration..duration) ⇒ <code>number</code>
* [~createCustom([duration], [defaultOrOptions], [options])](#module_@standards/duration..createCustom) ⇒ <code>duration</code>
* [~durationOptions](#module_@standards/duration..durationOptions) : <code>Object</code>
<a name="module_@standards/duration..duration"></a>
### @standards/duration~duration([duration], [defaultOrOptions], [options]) ⇒ <code>number</code>
Converts different types of string durations to milliseconds, seconds, minutes, and more as numbers.
**Returns**: <code>number</code> - The duration in number.
If the given duration is invalid, the returned duration will be `0` *(zero)*.
<table>
<thead>
<tr>
<th>Param</th><th>Type</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>[duration]</td><td><code>string</code> | <code>number</code> | <code>*</code></td><td><p>The duration(s) to parse.</p>
<p> Multiple durations are allowed in the string separated by spaces and/or commas.</p>
<p> Valid duration units: <strong>weeks</strong>, <strong>days</strong>, <strong>hours</strong>, <strong>minutes</strong>, <strong>seconds</strong>, and <strong>milliseconds</strong>.
Possible duration unit variations:</p>
<ul>
<li>milliseconds: <code>'ms'</code>, <code>'millisecond'</code>, <code>'milliseconds'</code></li>
<li>seconds: <code>'s'</code>, <code>'sec'</code>, <code>'second'</code>, <code>'seconds'</code></li>
<li>minutes: <code>'m'</code>, <code>'min'</code>, <code>'minute'</code>, <code>'minutes'</code></li>
<li>hours: <code>'h'</code>, <code>'hour'</code>, <code>'hours'</code></li>
<li>days: <code>'d'</code>, <code>'day'</code>, <code>'days'</code></li>
<li>weeks: <code>'w'</code>, <code>'week'</code>, <code>'weeks'</code></li>
</ul>
</td>
</tr><tr>
<td>[defaultOrOptions]</td><td><code>string</code> | <code>number</code> | <code>durationOptions</code></td><td><p>The default duration as a fallback or additional options.</p>
<p> If unspecified, the default fallback duration is 0 (zero).</p>
</td>
</tr><tr>
<td>[options]</td><td><code>durationOptions</code></td><td><p>Additional options to change the default behavior.</p>
</td>
</tr> </tbody>
</table>
**Example** *(General Usage)*
```js
// these will return milliseconds
duration('3.5h') // === 12600000
duration('1.5h') // === 5400000
duration('175min') // === 10500000
duration('300ms') // === 300
```
**Example** *(Unit Varieties)*
```js
// singulars, plurals, and shorthands work as expected
duration('2s') // === 2000
duration('2sec') // === 2000
duration('2second') // === 2000
duration('2seconds') // === 2000
duration('2 second') // === 2000
duration('2 seconds') // === 2000
```
**Example** *(Whitespaces)*
```js
// whitespaces don't matter
duration('42 sec') // === 42000
duration(' 42sec') // === 42000
duration('42sec ') // === 42000
duration(' 42 sec ') // === 42000
```
**Example** *(Separators)*
```js
// commas, underscores, and dashes are allowed
duration('10000 sec') // === 10000000
duration('10,000 sec') // === 10000000
duration('10_000 sec') // === 10000000
duration('10-000 sec') // === 10000000
```
**Example** *(Unit Tolerance)*
```js
// multiple units are allowed too, even the crazier ones
duration('1 hour 23 minutes 45 seconds 600 milliseconds') // === 5025600
duration('100ms 200ms') // === 300
duration('500ms 400ms 300ms 200ms 100ms') // === 1500
duration('1s 2sec 3secs 4second 5seconds') // === 15000
duration('1.1h 2.2h 3.3h 4.4h 5.5h') // === 59400000
duration('0.5d 1.0day 1.5day 2.0days') // === 432000000
```
**Example** *(Custom Fallback)*
```js
// these will return the fallback duration
duration(undefined, '1 hour') // === 3600000
duration(null, '45 min') // === 2700000
duration(false, '60sec') // === 60000
```
**Example** *(Custom Return Unit)*
```js
// 1 hour in seconds
duration('1 h', { unit: 's' }) // === 3600
// 2 days in minutes
duration('2 days', { unit: 'minutes' }) // === 2880
// 3 weeks, 5 days and 12 hours in hours
duration('3w 5days 12 h', { unit: 'h' }) // === 636
```
**Example** *(CommonJS Require)*
```js
const duration = require('@standards/duration')
duration('42 sec') // === 42000
```
**Example** *(ES Module Import)*
```js
import duration from '@standards/duration'
duration('42 sec') // === 42000
```
<a name="module_@standards/duration..createCustom"></a>
### @standards/duration~createCustom([duration], [defaultOrOptions], [options]) ⇒ <code>duration</code>
Creates a customized duration function with the given arguments.
**Returns**: <code>duration</code> - The customized duration function.
**See**: [@standards/duration~duration](@standards/duration~duration)
<table>
<thead>
<tr>
<th>Param</th><th>Type</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>[duration]</td><td><code>string</code> | <code>number</code> | <code>*</code></td><td><p>The duration(s) to parse.</p>
</td>
</tr><tr>
<td>[defaultOrOptions]</td><td><code>string</code> | <code>number</code> | <code>durationOptions</code></td><td><p>The default duration as a fallback or additional options.</p>
</td>
</tr><tr>
<td>[options]</td><td><code>durationOptions</code></td><td><p>Additional options to change the default behavior.</p>
</td>
</tr> </tbody>
</table>
**Example** *(CommonJS)*
```js
const duration = require('@standards/duration')
// custom duration function
// with 1 hour as a fallback, return unit is in seconds
const custom = duration.createCustom(null, '1 hour', { unit: 'sec' })
```
**Example** *(ES Module)*
```js
import { createCustom } from '@standards/duration'
// custom duration function
// with 1 hour as a fallback, return unit is in seconds
const custom = createCustom(null, '1 hour', { unit: 'sec' })
```
**Example** *(Custom Duration Function)*
```js
// will return the fallback, which is "1 hour" in seconds ({ unit: 'sec' })
custom() // === 3600
// will return 2 hours in seconds, since the return unit is "sec"
custom('2 hours') // === 7200
```
<a name="module_@standards/duration..durationOptions"></a>
### @standards/duration~durationOptions : <code>Object</code>
Additional options to change the default behavior.
**Properties**
<table>
<thead>
<tr>
<th>Name</th><th>Type</th><th>Default</th><th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>[unit]</td><td><code>string</code></td><td><code>"ms"</code></td><td><p>The unit in which the returned duration will be converted to.</p>
<p> By default, the returned duration will be in milliseconds (<code>'ms'</code>).
Possible units are the same as for the durations to parse (from milliseconds to weeks).</p>
</td>
</tr><tr>
<td>[round]</td><td><code>boolean</code></td><td><code>true</code></td><td><p>If true, the returned duration will be rounded. By default, it's <code>true</code>.</p>
</td>
</tr> </tbody>
</table>
**Example** *(Duration Options)*
```js
// without fallback
duration('42 sec', { unit: 'sec', round: false })
// with fallback
duration('42 sec', '1 sec', { unit: 'sec', round: false })
```
<!--- API %> --->
---
## :star: Related
Check out the [official website][url-website] for more tools, utilities, and packages.
Find more **@standards** packages on [NPM][url-npm] and [GitHub][url-github].
## :beers: Contribution
**Any contribution is ***highly*** appreciated**. To get going, check out the [**contribution guidelines**][url-contrib-doc].
***Thank you and have fun!***
## :copyright: License
[ISC][url-license-doc] @ [Richard King](https://www.richrdkng.com)
<!--- References ======================================================== --->
<!--- URLs --->
[url-license-doc]: https://github.com/js-standards/duration/blob/master/LICENSE.md
[url-contrib-doc]: https://github.com/js-standards/duration/blob/master/.github/CONTRIBUTING.md
[url-cdn]: https://www.jsdelivr.com/package/npm/@standards/duration?path=dist
[url-npm]: https://www.npmjs.com/search?q=keywords:@standards
[url-github]: https://github.com/js-standards
[url-website]: https://js-standards.github.io
[url-twitter]: https://twitter.com/_standards