Compare commits

...

9 Commits

Author SHA1 Message Date
ec25164cba testing 2022-07-16 17:34:20 +02:00
90fd28ef95 Merge branch 'master' of https://github.com/CupCakeArmy/uhrwerk 2022-07-16 17:29:27 +02:00
270b27d905 update deps and add esm support 2022-07-16 17:29:22 +02:00
750ad01d72 Update README.md 2021-03-15 18:46:33 +01:00
fc5b828270 Update README.md 2020-09-19 12:00:26 +02:00
72d460e41f Merge branch 'master' of https://github.com/CupCakeArmy/uhrwerk 2020-05-26 10:38:33 +02:00
c8231c3818 funding 2020-05-26 10:38:30 +02:00
1a7d00f9c9 Update README.md 2020-03-20 11:24:25 +01:00
e3e93d5083 Merge pull request #1 from cupcakearmy/add-license-1
Create LICENSE
2020-03-20 11:23:13 +01:00
10 changed files with 1402 additions and 224 deletions

1
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1 @@
github: cupcakearmy

5
.gitignore vendored
View File

@@ -1,5 +1,2 @@
node_modules node_modules
yarn.lock dist
lib
.idea

View File

@@ -1,3 +0,0 @@
*
!lib/index.js
!lib/index.d.ts

View File

@@ -1,4 +1,11 @@
# uhrwerk 🕰 # uhrwerk 🕰
![dependencies](https://badgen.net/david/dep/cupcakearmy/uhrwerk)
![downloads badge](https://badgen.net/npm/dt/uhrwerk)
![types badge](https://badgen.net/npm/types/uhrwerk)
![version badge](https://badgen.net/npm/v/uhrwerk)
![minzip size badge](https://badgen.net/bundlephobia/minzip/uhrwerk)
Minimal time duration utility. Replacement for MomentJS Durations. If you are looking into the time component of MomentJS check out this awesome library [dayjs](https://github.com/iamkun/dayjs). Minimal time duration utility. Replacement for MomentJS Durations. If you are looking into the time component of MomentJS check out this awesome library [dayjs](https://github.com/iamkun/dayjs).
📦 It's **tiny**: [1.6kB](https://bundlephobia.com/result?p=uhrwerk@1.0.0) vs moment js [231.7kb](https://bundlephobia.com/result?p=moment@latest) 📦 It's **tiny**: [1.6kB](https://bundlephobia.com/result?p=uhrwerk@1.0.0) vs moment js [231.7kb](https://bundlephobia.com/result?p=moment@latest)

View File

@@ -1,24 +1,36 @@
{ {
"name": "uhrwerk", "name": "uhrwerk",
"version": "1.0.2", "version": "1.1.0",
"description": "time utility", "description": "time utility",
"main": "./lib/index.js", "author": "Niccolo Borgioli",
"types": "./lib/index.d.ts", "license": "MIT",
"type": "module",
"scripts": { "scripts": {
"build": "tsc", "build": "tsup src/index.ts --format cjs,esm --dts --sourcemap",
"test": "yarn run build && mocha", "test": "pnpm run build && mocha",
"prepublishOnly": "npm run test" "prepublishOnly": "pnpm run test"
}, },
"main": "./dist/index.cjs",
"types": "./dist/index.d.ts",
"exports": {
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"files": [
"dist"
],
"keywords": [ "keywords": [
"time", "time",
"interval", "interval",
"humand-readable", "humand-readable",
"utility" "utility"
], ],
"author": "Niccolo Borgioli",
"license": "MIT",
"devDependencies": { "devDependencies": {
"mocha": "6.x", "mocha": "~10.0.0",
"typescript": "3.x" "tsup": "^6.1.3",
"typescript": "~4.7.4"
} }
} }

1173
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,25 @@
type Intervals = type Intervals =
'millisecond' | 'millisecond'
| 'milliseconds' | 'milliseconds'
| 'ms' | 'ms'
| 'second' | 'second'
| 'seconds' | 'seconds'
| 's' | 's'
| 'minute' | 'minute'
| 'minutes' | 'minutes'
| 'm' | 'm'
| 'hour' | 'hour'
| 'hours' | 'hours'
| 'h' | 'h'
| 'day' | 'day'
| 'days' | 'days'
| 'd' | 'd'
| 'week' | 'week'
| 'weeks' | 'weeks'
| 'w' | 'w'
| 'year' | 'year'
| 'years' | 'years'
| 'y' | 'y'
const Millisecond = 1 const Millisecond = 1
const Second = Millisecond * 1000 const Second = Millisecond * 1000
@@ -34,132 +34,128 @@ export type HumanizerReturnFN = (duration: Duration) => string
export type Humanizer = [HumanizerTestFN, HumanizerReturnFN][] export type Humanizer = [HumanizerTestFN, HumanizerReturnFN][]
const defaultHumanizer: Humanizer = [ const defaultHumanizer: Humanizer = [
[d => d.years() > 0, d => `${d.years()} years`], [(d) => d.years() > 0, (d) => `${d.years()} years`],
[d => d.weeks() > 1, d => `${d.weeks()} weeks`], [(d) => d.weeks() > 1, (d) => `${d.weeks()} weeks`],
[d => d.days() > 0, d => `${d.days()} days`], [(d) => d.days() > 0, (d) => `${d.days()} days`],
[d => d.hours() > 0, d => `${d.hours()} hours`], [(d) => d.hours() > 0, (d) => `${d.hours()} hours`],
[d => d.minutes() > 5, d => `${d.minutes()} minutes`], [(d) => d.minutes() > 5, (d) => `${d.minutes()} minutes`],
[d => d.minutes() > 0, _ => `a few minutes`], [(d) => d.minutes() > 0, (_) => `a few minutes`],
[() => true, () => `a moment`], [() => true, () => `a moment`],
] ]
export class Duration { export class Duration {
private duration: number
private duration: number constructor(amount: number, interval: Intervals) {
this.duration = Duration.ProcessInterval(amount, interval)
}
constructor(amount: number, interval: Intervals) { private static ProcessInterval(amount: number, interval: Intervals): number {
this.duration = Duration.ProcessInterval(amount, interval) switch (interval.toLowerCase()) {
} case 'millisecond':
case 'milliseconds':
case 'ms':
return amount * Millisecond
case 'second':
case 'seconds':
case 's':
return amount * Second
case 'minute':
case 'minutes':
case 'm':
return amount * Minute
case 'hour':
case 'hours':
case 'h':
return amount * Hour
case 'day':
case 'days':
case 'd':
return amount * Day
case 'week':
case 'weeks':
case 'w':
return amount * Week
case 'year':
case 'years':
case 'y':
return amount * Year
default:
throw new Error('Wrong interval')
}
}
private static ProcessInterval(amount: number, interval: Intervals): number { public add(amount: number, interval: Intervals): Duration {
switch (interval.toLowerCase()) { this.duration += Duration.ProcessInterval(amount, interval)
case 'millisecond': return this
case 'milliseconds': }
case 'ms':
return amount * Millisecond
case 'second':
case 'seconds':
case 's':
return amount * Second
case 'minute':
case 'minutes':
case 'm':
return amount * Minute
case 'hour':
case 'hours':
case 'h':
return amount * Hour
case 'day':
case 'days':
case 'd':
return amount * Day
case 'week':
case 'weeks':
case 'w':
return amount * Week
case 'year':
case 'years':
case 'y':
return amount * Year
default:
throw new Error('Wrong interval')
}
}
public add(amount: number, interval: Intervals): Duration { public subtract(amount: number, interval: Intervals): Duration {
this.duration += Duration.ProcessInterval(amount, interval) this.duration -= Duration.ProcessInterval(amount, interval)
return this return this
} }
public subtract(amount: number, interval: Intervals): Duration { public asMilliseconds(): number {
this.duration -= Duration.ProcessInterval(amount, interval) return this.duration
return this }
}
public asMilliseconds(): number { public asSeconds(): number {
return this.duration return this.duration / Second
} }
public asSeconds(): number { public asMinutes(): number {
return this.duration / Second return this.duration / Minute
} }
public asMinutes(): number { public asHours(): number {
return this.duration / Minute return this.duration / Hour
} }
public asHours(): number { public asDays(): number {
return this.duration / Hour return this.duration / Day
} }
public asDays(): number { public asWeeks(): number {
return this.duration / Day return this.duration / Week
} }
public asWeeks(): number { public asYears(): number {
return this.duration / Week return this.duration / Year
} }
public asYears(): number { public milliseconds(): number {
return this.duration / Year return ((((((this.duration % Year) % Day) % Hour) % Minute) % Second) / Millisecond) | 0
} }
public milliseconds(): number { public seconds(): number {
return (this.duration % Year % Day % Hour % Minute % Second) / Millisecond | 0 return (((((this.duration % Year) % Day) % Hour) % Minute) / Second) | 0
} }
public seconds(): number { public minutes(): number {
return (this.duration % Year % Day % Hour % Minute) / Second | 0 return ((((this.duration % Year) % Day) % Hour) / Minute) | 0
} }
public minutes(): number { public hours(): number {
return (this.duration % Year % Day % Hour) / Minute | 0 return (((this.duration % Year) % Day) / Hour) | 0
} }
public hours(): number { public days(): number {
return (this.duration % Year % Day) / Hour | 0 return ((this.duration % Year) / Day) | 0
} }
public days(): number { public weeks(): number {
return (this.duration % Year) / Day | 0 return (this.duration / Week) | 0
} }
public weeks(): number { public years(): number {
return (this.duration) / Week | 0 return (this.duration / Year) | 0
} }
public years(): number { public humanize(humanizer?: Humanizer): string {
return (this.duration) / Year | 0 if (!humanizer) humanizer = defaultHumanizer
}
public humanize(humanizer?: Humanizer): string { for (const [control, value] of humanizer) if (control(this)) return value(this)
if (!humanizer) humanizer = defaultHumanizer
for (const [control, value] of humanizer) return ''
if (control(this)) }
return value(this) }
return ''
}
}

View File

@@ -1,78 +0,0 @@
const { describe, it } = require('mocha')
const a = require('assert')
const { Duration } = require('../')
describe('Duration', () => {
describe('Basics', () => {
it('as unit', () => {
const d = new Duration(.5, 'year')
a.strictEqual(d.asMilliseconds(), 1000 * 60 * 60 * 24 * 365.25 / 2)
a.strictEqual(d.asSeconds(), 60 * 60 * 24 * 365.25 / 2)
a.strictEqual(d.asMinutes(), 60 * 24 * 365.25 / 2)
a.strictEqual(d.asHours(), 24 * 365.25 / 2)
a.strictEqual(d.asDays(), 365.25 / 2)
a.strictEqual(d.asWeeks(), 365.25 / 7 / 2)
a.strictEqual(d.asYears(), .5)
})
it('add / subtract', () => {
const d = new Duration(1, 'day')
d.add(4, 'hours')
a.strictEqual(d.asHours(), 28)
d.subtract(.5, 'day')
a.strictEqual(d.asHours(), 16)
})
it('exact units', () => {
const d = new Duration(1, 'day')
d.add(42, 'milliseconds')
a.strictEqual(d.milliseconds(), 42)
d.add(5, 'seconds')
a.strictEqual(d.seconds(), 5)
d.add(27, 'minutes')
a.strictEqual(d.minutes(), 27)
d.add(8, 'hours')
a.strictEqual(d.hours(), 8)
d.add(3, 'days')
a.strictEqual(d.days(), 4)
d.add(17, 'weeks')
a.strictEqual(d.weeks(), 17)
d.add(2, 'years')
a.strictEqual(d.years(), 2)
})
})
describe('Humanize', () => {
it('few minutes', () => {
a.strictEqual(new Duration(2, 'minutes').humanize(), 'a few minutes')
a.strictEqual(new Duration(16, 'minutes').humanize(), '16 minutes')
a.strictEqual(new Duration(30, 'seconds').humanize(), 'a moment')
})
it('custom humanizer', () => {
const humanizer = [
[d => d.days() > 0, d => `yus for ${d.days()}`],
[() => true, () => 'cool'],
]
const d = new Duration(5, 'minutes')
a.strictEqual(d.humanize(humanizer), 'cool')
d.add(2, 'days')
a.strictEqual(d.humanize(humanizer), `yus for 2`)
})
})
})

73
test/main.mjs Normal file
View File

@@ -0,0 +1,73 @@
import { strictEqual } from 'assert'
import { describe, it } from 'mocha'
import { Duration } from '../dist/index.js'
describe('Duration', () => {
describe('Basics', () => {
it('as unit', () => {
const d = new Duration(0.5, 'year')
strictEqual(d.asMilliseconds(), (1000 * 60 * 60 * 24 * 365.25) / 2)
strictEqual(d.asSeconds(), (60 * 60 * 24 * 365.25) / 2)
strictEqual(d.asMinutes(), (60 * 24 * 365.25) / 2)
strictEqual(d.asHours(), (24 * 365.25) / 2)
strictEqual(d.asDays(), 365.25 / 2)
strictEqual(d.asWeeks(), 365.25 / 7 / 2)
strictEqual(d.asYears(), 0.5)
})
it('add / subtract', () => {
const d = new Duration(1, 'day')
d.add(4, 'hours')
strictEqual(d.asHours(), 28)
d.subtract(0.5, 'day')
strictEqual(d.asHours(), 16)
})
it('exact units', () => {
const d = new Duration(1, 'day')
d.add(42, 'milliseconds')
strictEqual(d.milliseconds(), 42)
d.add(5, 'seconds')
strictEqual(d.seconds(), 5)
d.add(27, 'minutes')
strictEqual(d.minutes(), 27)
d.add(8, 'hours')
strictEqual(d.hours(), 8)
d.add(3, 'days')
strictEqual(d.days(), 4)
d.add(17, 'weeks')
strictEqual(d.weeks(), 17)
d.add(2, 'years')
strictEqual(d.years(), 2)
})
})
describe('Humanize', () => {
it('few minutes', () => {
strictEqual(new Duration(2, 'minutes').humanize(), 'a few minutes')
strictEqual(new Duration(16, 'minutes').humanize(), '16 minutes')
strictEqual(new Duration(30, 'seconds').humanize(), 'a moment')
})
it('custom humanizer', () => {
const humanizer = [
[(d) => d.days() > 0, (d) => `yus for ${d.days()}`],
[() => true, () => 'cool'],
]
const d = new Duration(5, 'minutes')
strictEqual(d.humanize(humanizer), 'cool')
d.add(2, 'days')
strictEqual(d.humanize(humanizer), `yus for 2`)
})
})
})

View File

@@ -1,6 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "esnext", "target": "es2020",
"module": "commonjs", "module": "commonjs",
"declaration": true, "declaration": true,
"outDir": "./lib", "outDir": "./lib",
@@ -20,4 +20,4 @@
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"esModuleInterop": true "esModuleInterop": true
} }
} }