Skip to content

Commit

Permalink
Add clamp function (#2498)
Browse files Browse the repository at this point in the history
Added a new `clamp` function that allows to bound a date to an interval.
  • Loading branch information
Liam-Tait committed Jul 23, 2021
1 parent 833cdfa commit 5304dcd
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/clamp/index.ts
@@ -0,0 +1,37 @@
import max from '../max'
import min from '../min'
import requiredArgs from '../_lib/requiredArgs/index'

/**
* @name clamp
* @category Interval Helpers
* @summary Return a date bounded by the start and the end of the given interval
*
* @description
* Clamps a date to the lower bound with the start of the interval and the upper
* bound with the end of the interval.
*
* - When the date is less than the start of the interval, the start is returned.
* - When the date is greater than the end of the interval, the end is returned.
* - Otherwise the date is returned.
*
* @example
* // What is Mar, 21, 2021 bounded to an interval starting at Mar, 22, 2021 and ending at Apr, 01, 2021
* const result = clamp(new Date(2021, 2, 21), {
* start: new Date(2021, 2, 22),
* end: new Date(2021, 3, 1),
* })
* //=> Mon Mar 22 2021 00:00:00
*
* @param {Date | Number} date - the date to be bounded
* @param {Interval} interval - the interval to bound to
* @returns {Date} the date bounded by the start and the end of the interval
* @throws {TypeError} 2 arguments required
*/
export default function clamp(
date: Date | number,
{ start, end }: Interval
): Date {
requiredArgs(2, arguments)
return min([max([date, start]), end])
}
43 changes: 43 additions & 0 deletions src/clamp/test.ts
@@ -0,0 +1,43 @@
import assert from 'assert'
import clamp from '.'

describe('clamp', () => {
it('accepts timestamps', () => {
const start = new Date(2000, 1, 1).getTime()
const date = new Date(2000, 1, 2).getTime()
const end = new Date(2000, 1, 3).getTime()
const result = clamp(date, { start, end })
assert.deepStrictEqual(result, new Date(2000, 1, 2))
})

it('returns the start date when the date is less than start', () => {
const start = new Date(2001, 1, 1)
const date = new Date(2000, 1, 1)
const end = new Date(2020, 1, 1)
const result = clamp(date, { start, end })
assert.deepStrictEqual(result, new Date(2001, 1, 1))
})

it('returns the end date when the date is greater than the end date', () => {
const start = new Date(2000, 1, 1)
const date = new Date(2003, 1, 1)
const end = new Date(2001, 1, 1)
const result = clamp(date, { start, end })
assert.deepStrictEqual(result, new Date(2001, 1, 1))
})

it('returns the date when the date is within the bound of start and end', () => {
const start = new Date(2000, 1, 1)
const date = new Date(2001, 1, 1)
const end = new Date(2003, 1, 1)
const result = clamp(date, { start, end })
assert.deepStrictEqual(result, new Date(2001, 1, 1))
})

it('throws TypeError exception if passed less than 2 arguments', () => {
// @ts-expect-error
assert.throws(clamp.bind(null), TypeError)
// @ts-expect-error
assert.throws(clamp.bind(null, 1), TypeError)
})
})
1 change: 1 addition & 0 deletions src/index.js
Expand Up @@ -13,6 +13,7 @@ export { default as addSeconds } from './addSeconds/index'
export { default as addWeeks } from './addWeeks/index'
export { default as addYears } from './addYears/index'
export { default as areIntervalsOverlapping } from './areIntervalsOverlapping/index'
export { default as clamp } from './clamp/index'
export { default as closestIndexTo } from './closestIndexTo/index'
export { default as closestTo } from './closestTo/index'
export { default as compareAsc } from './compareAsc/index'
Expand Down

0 comments on commit 5304dcd

Please sign in to comment.