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 new set function #1398

Merged
merged 1 commit into from Sep 12, 2019
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
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'
jmannanc marked this conversation as resolved.
Show resolved Hide resolved
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
jmannanc marked this conversation as resolved.
Show resolved Hide resolved
* // 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))
})
jmannanc marked this conversation as resolved.
Show resolved Hide resolved

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)
})
})
})