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

Add clamp function #2498

Merged
merged 5 commits into from Jul 23, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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