Skip to content

Commit

Permalink
Add new set function
Browse files Browse the repository at this point in the history
  • Loading branch information
jmannanc committed Sep 12, 2019
1 parent c3502f6 commit 52ccbb1
Show file tree
Hide file tree
Showing 8 changed files with 368 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/fp/set/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

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

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

var set = convertToFP(fn, 2)

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

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

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<Object, Date | number, Date>
25 changes: 25 additions & 0 deletions src/set/benchmark.js
@@ -0,0 +1,25 @@
// @flow
/* eslint-env mocha */
/* global suite, benchmark */

import set from '.'
import moment from 'moment'

suite(
'set',
function() {
benchmark('date-fns', function() {
return set(this.date, { year: 2014, month: 8 })
})

benchmark('Moment.js', function() {
return this.moment.set({ year: 2014, month: 3 })
})
},
{
setup: function() {
this.date = new Date(2013, 7)
this.moment = moment()
}
}
)
4 changes: 4 additions & 0 deletions src/set/index.d.ts
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import { set } from 'date-fns'
export default set
91 changes: 91 additions & 0 deletions src/set/index.js
@@ -0,0 +1,91 @@
import toDate from '../toDate/index.js'
import setMonth from '../setMonth/index.js'
import toInteger from '../_lib/toInteger/index.js'

/**
* @name set
* @category Common Helpers
* @summary Set date values to a given date.
*
* @description
* Set date values to a given date.
*
* Sets time values to date from object `values`.
* A value is not set if it is undefined or null or doesn't exist in `values`.
*
* Note about bundle size: `set` does not internally use `setX` functions from date-fns but instead opts
* to use native `Date#setX` methods. If you use this function, you may not want to include the
* other `setX` functions that date-fns provides if you are concerned about the bundle size.
*
* @param {Date|Number} date - the date to be changed
* @param {Object} values - an object with options
* @param {Number} values.year - the number of years to be set
* @param {Number} values.month - the number of months to be set
* @param {Number} values.date - the number of days to be set
* @param {Number} values.hours - the number of hours to be set
* @param {Number} values.minutes - the number of minutes to be set
* @param {Number} values.seconds - the number of seconds to be set
* @param {Number} values.milliseconds - the number of milliseconds to be set
* @returns {Date} the new date with options set
* @throws {TypeError} 2 arguments required
* @throws {RangeError} `values` must be an object
*
* @example
* // Transform 1 September 2014 into 20 October 2015 in a single line:
* var result = set(new Date(2014, 8, 20), { year: 2015, month: 9, date: 20 })
* //=> Tue Oct 20 2015 00:00:00
*
* @example
* // Set 12 PM to 1 September 2014 01:23:45 to 1 September 2014 12:00:00:
* var result = set(new Date(2014, 8, 1, 1, 23, 45), { hours: 12 })
* //=> Mon Sep 01 2014 12:23:45
*/

export default function set(dirtyDate, values) {
if (arguments.length < 2) {
throw new TypeError(
'2 arguments required, but only ' + arguments.length + ' present'
)
}

if (typeof values !== 'object' || values === null) {
throw new RangeError('values parameter must be an object')
}

var date = toDate(dirtyDate)

// Check if date is Invalid Date because Date.prototype.setFullYear ignores the value of Invalid Date
if (isNaN(date)) {
return new Date(NaN)
}

if (values.year != null) {
date.setFullYear(values.year)
}

if (values.month != null) {
date = setMonth(date, values.month)
}

if (values.date != null) {
date.setDate(toInteger(values.date))
}

if (values.hours != null) {
date.setHours(toInteger(values.hours))
}

if (values.minutes != null) {
date.setMinutes(toInteger(values.minutes))
}

if (values.seconds != null) {
date.setSeconds(toInteger(values.seconds))
}

if (values.milliseconds != null) {
date.setMilliseconds(toInteger(values.milliseconds))
}

return date
}
49 changes: 49 additions & 0 deletions src/set/index.js.flow
@@ -0,0 +1,49 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

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

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 | number,
values: {
year?: number,
month?: number,
date?: number,
hours?: number,
minutes?: number,
seconds?: number,
milliseconds?: number
}
) => Date
143 changes: 143 additions & 0 deletions src/set/test.js
@@ -0,0 +1,143 @@
// @flow
/* eslint-env mocha */

import assert from 'power-assert'
import set from '.'

describe('set', function() {
it('sets all values', function() {
var result = set(new Date(2013), {
year: 2014,
month: 8, // Sep
date: 20,
hours: 12,
minutes: 12,
seconds: 12,
milliseconds: 12
})
assert.deepEqual(
result.toString(),
new Date(2014, 8 /* Sep */, 20, 12, 12, 12, 12).toString()
)
})

it('sets year', function() {
var result = set(new Date(2013, 8 /* Sep */), { year: 2014 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */))
})

it('sets month', function() {
var result = set(new Date(2014, 8 /* Sep */), { month: 9 /* Oct */ })
assert.deepEqual(result, new Date(2014, 9 /* Oct */))
})

it('sets day of month', function() {
var result = set(new Date(2014, 8 /* Sep */), { date: 20 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20))
})

it('sets hours', function() {
var result = set(new Date(2014, 8 /* Sep */, 1), { hours: 12 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 12))
})

it('sets minutes', function() {
var result = set(new Date(2014, 8 /* Sep */, 1, 1), { minutes: 12 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 1, 12))
})

it('sets seconds', function() {
var result = set(new Date(2014, 8 /* Sep */, 1, 1, 1), { seconds: 12 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 1, 1, 12))
})

it('sets milliseconds', function() {
var result = set(new Date(2014, 8 /* Sep */, 1, 1, 1, 1), {
milliseconds: 500
})
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 1, 1, 1, 500))
})

describe('value overflow', function() {
it('months overflow into years', function() {
var result = set(new Date(2014, 8 /* Sep */, 1), {
month: 12 /* 13th month */
})
assert.deepEqual(result, new Date(2015, 0 /* Jan */, 1))
})

it('days of months overflow into months', function() {
var result = set(new Date(2014, 8 /* Sep */, 1), { date: 31 })
assert.deepEqual(result, new Date(2014, 9 /* Oct */, 1))
})

it('hours overflow into days', function() {
var result = set(new Date(2014, 8 /* Sep */, 19), { hours: 24 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20))
})

it('minutes overflow into hours', function() {
var result = set(new Date(2014, 8 /* Sep */, 20, 11), { minutes: 60 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20, 12))
})

it('seconds overflow into minutes', function() {
var result = set(new Date(2014, 8 /* Sep */, 20, 12, 58), { seconds: 60 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20, 12, 59))
})

it('milliseconds overflow into seconds', function() {
var result = set(new Date(2014, 8 /* Sep */, 20, 12, 58, 30), {
milliseconds: 1000
})
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 20, 12, 58, 31))
})
})

describe('edge cases', function() {
it('sets January', function() {
var result = set(new Date(2014, 8 /* Sep */), { month: 0 /* Jan */ })
assert.deepEqual(result, new Date(2014, 0 /* Jan */))
})

it('sets the last day of new month if the initial date was the last day of a longer month', function() {
var result = set(new Date(2014, 7 /* Aug */, 31), { month: 8 /* Sep */ })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 30))
})

it('ignores undefined values', function() {
var result = set(new Date(2014, 8 /* Sep */), { year: undefined })
assert.deepEqual(result, new Date(2014, 8 /* Sep */))
})

it('ignores null values', function() {
// $ExpectedMistake
var result = set(new Date(2014, 8 /* Sep */), { year: null })
assert.deepEqual(result, new Date(2014, 8 /* Sep */))
})

it('throws TypeError exception if passed less than 2 arguments', function() {
assert.throws(set.bind(null), TypeError)
})

it('returns Invalid Date if any value in values is NaN', function() {
var result = set(new Date(2014, 8 /* Sep */), { year: NaN })
assert.deepEqual(isNaN(result), isNaN(new Date(NaN)))
})

it('returns Invalid Date the initial date was Invalid Date as well', function() {
var result = set(new Date(NaN), { year: 2019 })
assert.deepEqual(isNaN(result), isNaN(new Date(NaN)))
})

it('throws RangeError exception if `values` is not an object', function() {
// $ExpectedMistake
assert.throws(set.bind(null, new Date(), true), RangeError)
})

it('throws RangeError exception if `values` is null', function() {
// $ExpectedMistake
assert.throws(set.bind(null, new Date(), null), RangeError)
})
})
})

0 comments on commit 52ccbb1

Please sign in to comment.