Skip to content

Commit

Permalink
add option nearestTo
Browse files Browse the repository at this point in the history
  • Loading branch information
xkizer committed Oct 14, 2018
1 parent a0dc42a commit dd4f96e
Show file tree
Hide file tree
Showing 14 changed files with 258 additions and 18 deletions.
4 changes: 2 additions & 2 deletions src/fp/index.js.flow
Expand Up @@ -282,8 +282,8 @@ declare module.exports: {
minWithOptions: CurriedFn2<Options, (Date | string | number)[], Date>,
parse: CurriedFn3<Date | string | number, string, string, Date>,
parseWithOptions: CurriedFn4<Options, Date | string | number, string, string, Date>,
roundToNearestMinutes: CurriedFn1<Date | string | number, Date>,
roundToNearestMinutesWithOptions: CurriedFn2<Options, Date | string | number, Date>,
roundToNearestMinutes: CurriedFn2<number, Date | string | number, Date>,
roundToNearestMinutesWithOptions: CurriedFn3<Options, number, Date | string | number, Date>,
setDate: CurriedFn2<number, Date | string | number, Date>,
setDateWithOptions: CurriedFn3<Options, number, Date | string | number, Date>,
setDay: CurriedFn2<number, Date | string | number, Date>,
Expand Down
4 changes: 4 additions & 0 deletions src/fp/roundToNearestMinutes/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import {roundToNearestMinutes} from 'date-fns/fp'
export = roundToNearestMinutes
8 changes: 8 additions & 0 deletions src/fp/roundToNearestMinutes/index.js
@@ -0,0 +1,8 @@
// This file is generated automatically by `scripts/build/fp.js`. Please, don't change it.

import fn from '../../roundToNearestMinutes/index.js'
import convertToFP from '../_lib/convertToFP/index.js'

var roundToNearestMinutes = convertToFP(fn, 2)

export default roundToNearestMinutes
55 changes: 55 additions & 0 deletions src/fp/roundToNearestMinutes/index.js.flow
@@ -0,0 +1,55 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

type Interval = {
start: Date | string | number,
end: Date | string | number
}

type Options = {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
unit?: 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year',
roundingMethod?: 'floor' | 'ceil' | 'round',
awareOfUnicodeTokens?: boolean
}

type Locale = {
formatDistance: Function,
formatRelative: Function,
localize: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
formatLong: Object,
date: Function,
time: Function,
dateTime: Function,
match: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
options?: {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
}

type CurriedFn1<A, R> = <A>(a: A) => R

type CurriedFn2<A, B, R> = <A>(a: A) => CurriedFn1<B, R>
| <A, B>(a: A, b: B) => R

declare module.exports: CurriedFn2<number, Date | string | number, Date>
4 changes: 4 additions & 0 deletions src/fp/roundToNearestMinutesWithOptions/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import {roundToNearestMinutesWithOptions} from 'date-fns/fp'
export = roundToNearestMinutesWithOptions
8 changes: 8 additions & 0 deletions src/fp/roundToNearestMinutesWithOptions/index.js
@@ -0,0 +1,8 @@
// This file is generated automatically by `scripts/build/fp.js`. Please, don't change it.

import fn from '../../roundToNearestMinutes/index.js'
import convertToFP from '../_lib/convertToFP/index.js'

var roundToNearestMinutesWithOptions = convertToFP(fn, 3)

export default roundToNearestMinutesWithOptions
59 changes: 59 additions & 0 deletions src/fp/roundToNearestMinutesWithOptions/index.js.flow
@@ -0,0 +1,59 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

type Interval = {
start: Date | string | number,
end: Date | string | number
}

type Options = {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
unit?: 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year',
roundingMethod?: 'floor' | 'ceil' | 'round',
awareOfUnicodeTokens?: boolean
}

type Locale = {
formatDistance: Function,
formatRelative: Function,
localize: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
formatLong: Object,
date: Function,
time: Function,
dateTime: Function,
match: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
options?: {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
}

type CurriedFn1<A, R> = <A>(a: A) => R

type CurriedFn2<A, B, R> = <A>(a: A) => CurriedFn1<B, R>
| <A, B>(a: A, b: B) => R

type CurriedFn3<A, B, C, R> = <A>(a: A) => CurriedFn2<B, C, R>
| <A,B>(a: A, b: B) => CurriedFn1<C, R>
| <A,B,C>(a: A, b: B, c: C) => R

declare module.exports: CurriedFn3<Options, number, Date | string | number, Date>
10 changes: 8 additions & 2 deletions src/fp/test.js
Expand Up @@ -1308,12 +1308,18 @@ describe('FP functions', function () {
})

it('roundToNearestMinutes', function () {
var result = fp.roundToNearestMinutes()(new Date(2014, 6 /* Jul */, 10, 12, 10, 34, 99))
var result = fp.roundToNearestMinutes(5)(new Date(2014, 6 /* Jul */, 10, 12, 11, 34, 99))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 10))

var result = fp.roundToNearestMinutes()(new Date(2014, 6 /* Jul */, 10, 12, 11, 34, 99))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 11))
})

it('roundToNearestMinutesWithOptions', function () {
var result = fp.addMinutesWithOptions({})()(new Date(2014, 6 /* Jul */, 10, 12, 10, 34, 99))
var result = fp.roundToNearestMinutesWithOptions({})(5)(new Date(2014, 6 /* Jul */, 10, 12, 11, 34, 99))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 10))

var result = fp.roundToNearestMinutesWithOptions({})()(new Date(2014, 6 /* Jul */, 10, 12, 11, 34, 99))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 11))
})

Expand Down
1 change: 1 addition & 0 deletions src/index.js.flow
Expand Up @@ -653,6 +653,7 @@ declare module.exports: {

roundToNearestMinutes: (
date: Date | string | number,
nearestTo?: number,
options?: Options
) => Date,

Expand Down
4 changes: 4 additions & 0 deletions src/roundToNearestMinutes/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import {roundToNearestMinutes} from 'date-fns'
export = roundToNearestMinutes
25 changes: 21 additions & 4 deletions src/roundToNearestMinutes/index.js
@@ -1,4 +1,5 @@
import toDate from '../toDate'
import toInteger from '../_lib/toInteger'

/**
* @name roundToNearestMinutes
Expand All @@ -9,24 +10,40 @@ import toDate from '../toDate'
* Rounds the given date to the nearest minute
*
* @param {Date|String|Number} date - the date to round
* @param {Number} [nearestTo=1] - the closest minute to round to, must be between 1 and 30 inclusive
* @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options}
* @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate}
* @returns {Date} the new date rounded to the closest minute
* @throws {TypeError} 1 argument required
* @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2
* @throws {RangeError} `nearestTo` must be between 1 and 30
*
* @example
* // Round 10 July 2014 12:12:34 to nearest minute:
* var result = roundToNearestMinutes(new Date(2014, 6, 10, 12, 12, 34))
* //=> Thu Jul 10 2014 12:13:00
*/
export default function roundToNearestMinutes (dirtyDate, dirtyOptions) {
export default function roundToNearestMinutes (dirtyDate, dirtyNearestTo, dirtyOptions) {
if (arguments.length < 1) {
throw new TypeError('1 argument required, but only none provided present')
}

var nearestTo = arguments.length === 1 ? 1 : toInteger(dirtyNearestTo)

if (arguments.length === 2 && typeof dirtyNearestTo !== 'number' && typeof dirtyNearestTo !== 'string') {
dirtyOptions = dirtyNearestTo
nearestTo = 1
}

if (!nearestTo || nearestTo > 30 || nearestTo < 1) {
throw new RangeError('nearestTo must be between 1 and 30')
}

var date = toDate(dirtyDate, dirtyOptions)
var addedMinute = date.getSeconds() >= 30 ? 1 : 0
var seconds = date.getSeconds() // relevant if nearestTo is 1, which is the default case
var minutes = date.getMinutes() + seconds / 60
var roundedMinutes = Math.floor(minutes / nearestTo) * nearestTo
var remainderMinutes = minutes % nearestTo
var addedMinutes = Math.round(remainderMinutes / nearestTo) * nearestTo

return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes() + addedMinute)
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), roundedMinutes + addedMinutes)
}
54 changes: 54 additions & 0 deletions src/roundToNearestMinutes/index.js.flow
@@ -0,0 +1,54 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

type Interval = {
start: Date | string | number,
end: Date | string | number
}

type Options = {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7,
additionalDigits?: 0 | 1 | 2,
locale?: Locale,
includeSeconds?: boolean,
addSuffix?: boolean,
unit?: 'second' | 'minute' | 'hour' | 'day' | 'month' | 'year',
roundingMethod?: 'floor' | 'ceil' | 'round',
awareOfUnicodeTokens?: boolean
}

type Locale = {
formatDistance: Function,
formatRelative: Function,
localize: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
formatLong: Object,
date: Function,
time: Function,
dateTime: Function,
match: {
ordinalNumber: Function,
era: Function,
quarter: Function,
month: Function,
day: Function,
dayPeriod: Function
},
options?: {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
}

declare module.exports: (
date: Date | string | number,
nearestTo?: number,
options?: Options
) => Date
29 changes: 23 additions & 6 deletions src/roundToNearestMinutes/test.js
Expand Up @@ -5,7 +5,7 @@ import assert from 'power-assert'
import roundToNearestMinutes from '.'

describe('roundToNearestMinutes', function () {
it('rounds given date to the nearest minute', function () {
it('rounds given date to the nearest minute by default', function () {
var result = roundToNearestMinutes(new Date(2014, 6 /* Jul */, 10, 12, 16, 16))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 16, 0))
})
Expand All @@ -24,12 +24,17 @@ describe('roundToNearestMinutes', function () {
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 13, 0))
})

it('rounds up 30 seconds and above', function () {
var result = roundToNearestMinutes(new Date(2014, 6 /* Jul */, 10, 12, 10, 30))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 11, 0))
it('rounds to the closest x minutes if nearestTo is provided', function () {
var result = roundToNearestMinutes(new Date(2014, 6 /* Jul */, 10, 12, 10, 30), 4)
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 12, 0))
})

it('rounds down <30 seconds', function () {
it('rounds up >=30 seconds for nearestTo=1', function () {
var result = roundToNearestMinutes(new Date(2014, 6 /* Jul */, 10, 12, 13, 30))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 14, 0))
})

it('rounds down <30 seconds for nearestTo=1', function () {
var result = roundToNearestMinutes(new Date(2014, 6 /* Jul */, 10, 12, 13, 29, 999))
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 13, 0))
})
Expand All @@ -40,6 +45,12 @@ describe('roundToNearestMinutes', function () {
assert.deepEqual(date, new Date(2014, 6 /* Jul */, 10, 12, 10, 10, 99))
})

it('treats second arg as options if not string or number', function () {
// $ExpectedMistake
var result = roundToNearestMinutes(new Date(2014, 6 /* Jul */, 10, 12, 13, 29, 999), {})
assert.deepEqual(result, new Date(2014, 6 /* Jul */, 10, 12, 13, 0))
})

it('returns `Invalid Date` if the given date is invalid', function () {
var result = roundToNearestMinutes(new Date(NaN))
assert(result instanceof Date && isNaN(result))
Expand All @@ -51,7 +62,13 @@ describe('roundToNearestMinutes', function () {
assert.throws(block, RangeError)
})

it('throws TypeError exception if passed less than 1 argument', function () {
it('throws `TypeError` exception if passed less than 1 argument', function () {
assert.throws(roundToNearestMinutes.bind(null), TypeError)
})

it('throws `RangeError` if nearestTo is not between 1 and 30', function () {
var date = new Date(2014, 6 /* Jul */, 10, 12, 10, 30)
assert.throws(roundToNearestMinutes.bind(null, date, 31), RangeError)
assert.throws(roundToNearestMinutes.bind(null, date, 0), RangeError)
})
})

0 comments on commit dd4f96e

Please sign in to comment.