Skip to content

Commit

Permalink
New add function that allows adding a duration to a date (#1581) (closes
Browse files Browse the repository at this point in the history
  • Loading branch information
Anshuman71 authored and kossnocorp committed Jan 4, 2020
1 parent 16a561d commit 6266fa2
Show file tree
Hide file tree
Showing 14 changed files with 353 additions and 2 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@ This change log follows the format documented in [Keep a CHANGELOG].

## Unreleased

Thanks to [@mborgbrant](https://github.com/mborgbrant), [@saintplay](https://github.com/saintplay), [@mrenty](https://github.com/mrenty).
Thanks to [@mborgbrant](https://github.com/mborgbrant), [@saintplay](https://github.com/saintplay), [@mrenty](https://github.com/mrenty), [@kibertoad](https://github.com/kibertoad), [@levibuzolic](https://github.com/levibuzolic).

### Added

- [Added `eachMonthOfInterval` and `eachYearOfInterval`](https://github.com/date-fns/date-fns/pull/618).
- [Added `inclusive` option to `areIntervalsOverlapping](https://github.com/date-fns/date-fns/pull/643).
- [Added `isExists` function that checks if the given date is exists]().
- [Added `isExists` function that checks if the given date is exists](https://github.com/date-fns/date-fns/pull/682).
- [Added `add` function to add seconds, minutes, hours, weeks, years in single call](https://github.com/date-fns/date-fns/pull/1504).

### Changed

- [Reduced the total minified build size by 1Kb/4%](https://github.com/date-fns/date-fns/pull/1563).

## [2.8.1] - 2019-11-22

Expand Down
25 changes: 25 additions & 0 deletions src/add/benchmark.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// @flow
/* eslint-env mocha */
/* global suite, benchmark */

import add from '.'
import moment from 'moment'

suite(
'add',
function() {
benchmark('date-fns', function() {
return add(this.date, { hours: 5, minutes: 10 })
})

benchmark('Moment.js', function() {
return this.moment.add({ hours: 5, minutes: 10 }, 'seconds')
})
},
{
setup: function() {
this.date = new Date()
this.moment = moment()
}
}
)
4 changes: 4 additions & 0 deletions src/add/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

import { add } from 'date-fns'
export default add
66 changes: 66 additions & 0 deletions src/add/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import addMonths from '../addMonths/index.js'
import toDate from '../toDate/index.js'
import requiredArgs from '../_lib/requiredArgs/index.js'
import toInteger from '../_lib/toInteger/index.js'

/**
* @name add
* @category Common Helpers
* @summary Add the specified years, months, days, hours, minutes and seconds to the given date.
*
* @description
* Add the specified years, months, days, hours, minutes and seconds to the given date.
*
* @param {Date|Number} date - the date to be changed
* @param {Object} duration - the object with years, months, days, hours, minutes and seconds to be added
*
* | Key | Description |
* |----------------|------------------------------------|
* | years | Amount of years to be added |
* | months | Amount of months to be added |
* | days | Amount of days to be added |
* | hours | Amount of hours to be added |
* | minutes | Amount of minutes to be added |
* | seconds | Amount of seconds to be added |
*
* All values default to 0
*
* @returns {Date} the new date with the seconds added
* @throws {TypeError} 2 arguments required
*
* @example
* // Add the following duration to 1 September 2014, 10:19:50
* var result = add(new Date(2014, 8, 1, 10, 19, 50), {
* years: 2,
* months: 24,
* days: 7,
* hours: 5,
* minutes: 9,
* seconds: 30,
* })
* //=> Sat Sep 8 2018 15:29:20
*/
export default function add(dirtyDate, duration) {
requiredArgs(2, arguments)

if (!duration || typeof duration !== 'object') return new Date(NaN)

const years = 'years' in duration ? toInteger(duration.years) : 0
const months = 'months' in duration ? toInteger(duration.months) : 0
const days = 'days' in duration ? toInteger(duration.days) : 0
const hours = 'hours' in duration ? toInteger(duration.hours) : 0
const minutes = 'minutes' in duration ? toInteger(duration.minutes) : 0
const seconds = 'seconds' in duration ? toInteger(duration.seconds) : 0

// Add years and months
const dateWithMonths = addMonths(toDate(dirtyDate), months + years * 12)

// Add days, hours, minutes and seconds
const hoursToAdd = hours + days * 24
const minutesToAdd = minutes + hoursToAdd * 60
const secondsToAdd = seconds + minutesToAdd * 60
const msToAdd = secondsToAdd * 1000
const finalDate = new Date(dateWithMonths.getTime() + msToAdd)

return finalDate
}
38 changes: 38 additions & 0 deletions src/add/index.js.flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// @flow
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

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

export type Locale = {
formatDistance: (...args: Array<any>) => any,
formatRelative: (...args: Array<any>) => any,
localize: {
ordinalNumber: (...args: Array<any>) => any,
era: (...args: Array<any>) => any,
quarter: (...args: Array<any>) => any,
month: (...args: Array<any>) => any,
day: (...args: Array<any>) => any,
dayPeriod: (...args: Array<any>) => any
},
formatLong: Object,
date: (...args: Array<any>) => any,
time: (...args: Array<any>) => any,
dateTime: (...args: Array<any>) => any,
match: {
ordinalNumber: (...args: Array<any>) => any,
era: (...args: Array<any>) => any,
quarter: (...args: Array<any>) => any,
month: (...args: Array<any>) => any,
day: (...args: Array<any>) => any,
dayPeriod: (...args: Array<any>) => any
},
options?: {
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6,
firstWeekContainsDate?: 1 | 2 | 3 | 4 | 5 | 6 | 7
}
}

declare module.exports: (date: Date | number, duration: Object) => Date
78 changes: 78 additions & 0 deletions src/add/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// @flow
/* eslint-env mocha */

import assert from 'power-assert'
import add from '.'

describe('add', function() {
it('adds the values from the given object', function() {
var result = add(new Date(2014, 8 /* Sep */, 1, 10, 19, 50), {
seconds: 30,
minutes: 9,
hours: 5,
days: 7,
months: 9,
years: 2
})
assert.deepEqual(result, new Date(2017, 5 /* June */, 8, 15, 29, 20))
})

it('returns same date object when passed empty duration values', function() {
var result = add(new Date(2014, 8 /* Sep */, 1, 10).getTime(), {})
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 10))
})

it('accepts a timestamp', function() {
var result = add(new Date(2014, 8 /* Sep */, 1, 10).getTime(), { hours: 4 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 14))
})

it('converts a fractional number to an integer', function() {
var result = add(new Date(2014, 8 /* Sep */, 1, 10), { hours: 4.2 })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 14))
})

it('implicitly converts number arguments', function() {
var result = add(new Date(2014, 8 /* Sep */, 1, 10), { hours: '4.2' })
assert.deepEqual(result, new Date(2014, 8 /* Sep */, 1, 14))
})

it('does not mutate the original date', function() {
var date = new Date(2014, 8 /* Sep */, 1, 10)
add(date, { hours: 4 })
assert.deepEqual(date, new Date(2014, 8 /* Sep */, 1, 10))
})

it('works well if the desired month has fewer days and the provided date is in the last day of a month', function() {
var date = new Date(2014, 11 /* Dec */, 31)
var result = add(date, { months: 9 })
assert.deepEqual(result, new Date(2015, 8 /* Sep */, 30))
})

it('handles dates before 100 AD', function() {
var initialDate = new Date(0)
initialDate.setFullYear(-1, 10 /* Nov */, 30)
initialDate.setHours(0, 0, 0, 0)
var expectedResult = new Date(0)
expectedResult.setFullYear(0, 1 /* Feb */, 29)
expectedResult.setHours(0, 0, 0, 0)
var result = add(initialDate, { months: 3 })
assert.deepEqual(result, expectedResult)
})

it('returns `Invalid Date` if the given date is invalid', function() {
var result = add(new Date(NaN), { hours: 5 })
assert(result instanceof Date && isNaN(result))
})

it('throws RangeError exception if passed Number as duration', function() {
// $ExpectedMistake
const result = add(new Date(2014, 8, 1), 'wut')
assert(result instanceof Date && isNaN(result))
})

it('throws TypeError exception if passed less than 2 arguments', function() {
assert.throws(add.bind(null), TypeError)
assert.throws(add.bind(null, 1), TypeError)
})
})
4 changes: 4 additions & 0 deletions src/fp/add/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it.

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

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

var add = convertToFP(fn, 2)

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

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

export type Locale = {
formatDistance: (...args: Array<any>) => any,
formatRelative: (...args: Array<any>) => any,
localize: {
ordinalNumber: (...args: Array<any>) => any,
era: (...args: Array<any>) => any,
quarter: (...args: Array<any>) => any,
month: (...args: Array<any>) => any,
day: (...args: Array<any>) => any,
dayPeriod: (...args: Array<any>) => any
},
formatLong: Object,
date: (...args: Array<any>) => any,
time: (...args: Array<any>) => any,
dateTime: (...args: Array<any>) => any,
match: {
ordinalNumber: (...args: Array<any>) => any,
era: (...args: Array<any>) => any,
quarter: (...args: Array<any>) => any,
month: (...args: Array<any>) => any,
day: (...args: Array<any>) => any,
dayPeriod: (...args: Array<any>) => any
},
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>
1 change: 1 addition & 0 deletions src/fp/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This file is generated automatically by `scripts/build/indices.js`. Please, don't change it.

export { default as add } from './add/index.js'
export { default as addBusinessDays } from './addBusinessDays/index.js'
export { default as addDays } from './addDays/index.js'
export { default as addHours } from './addHours/index.js'
Expand Down
1 change: 1 addition & 0 deletions src/fp/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type CurriedFn4<A, B, C, D, R> = <A>(
) => CurriedFn1<D, R> | (<A, B, C, D>(a: A, b: B, c: C, d: D) => R)))

declare module.exports: {
add: CurriedFn2<Object, Date | number, Date>,
addBusinessDays: CurriedFn2<number, Date | number, Date>,
addDays: CurriedFn2<number, Date | number, Date>,
addHours: CurriedFn2<number, Date | number, Date>,
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// This file is generated automatically by `scripts/build/indices.js`. Please, don't change it.

export { default as add } from './add/index.js'
export { default as addBusinessDays } from './addBusinessDays/index.js'
export { default as addDays } from './addDays/index.js'
export { default as addHours } from './addHours/index.js'
Expand Down
2 changes: 2 additions & 0 deletions src/index.js.flow
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ export type Locale = {
}

declare module.exports: {
add: (date: Date | number, duration: Object) => Date,

addBusinessDays: (date: Date | number, amount: number) => Date,

addDays: (date: Date | number, amount: number) => Date,
Expand Down

0 comments on commit 6266fa2

Please sign in to comment.