diff --git a/CHANGELOG.md b/CHANGELOG.md index baa8aa0bc4..c78e5bfe79 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,14 +5,27 @@ This project adheres to [Semantic Versioning]. This change log follows the format documented in [Keep a CHANGELOG]. -[Semantic Versioning]: http://semver.org/ -[Keep a CHANGELOG]: http://keepachangelog.com/ +[semantic versioning]: http://semver.org/ +[keep a changelog]: http://keepachangelog.com/ ## [Unreleased] [See v2 Pre-Releases Change Log](https://gist.github.com/kossnocorp/a307a464760b405bb78ef5020a4ab136) for the list of changes made since `v2.0.0-alpha.1`. +### Added + +- Added new feature `differenceInBusinessDays`, + which counts all days in a range, except for weekends. + + ```javascript + var amountOfBusinessDays = differenceInBusinessDays( + new Date(2018, 0, 1), + new Date(2019, 0, 1) + ) + // => 261 (52 weekends excluded = 104 days skipped) + ``` + ### Fixed - Fix the `toDate` bug occurring when parsing ISO-8601 style dates (but not valid ISO format) @@ -63,157 +76,157 @@ for the list of changes made since `v2.0.0-alpha.1`. which is based on [Unicode Technical Standard #35](https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table). See [this post](https://blog.date-fns.org/post/unicode-tokens-in-date-fns-v2-sreatyki91jg) for more details. - | Unit | Pattern | Result examples | - |---------------------------------|---------|-----------------------------------| - | Era | G..GGG | AD, BC | - | | GGGG | Anno Domini, Before Christ | - | | GGGGG | A, B | - | Calendar year | y | 44, 1, 1900, 2017 | - | | yo | 44th, 1st, 0th, 17th | - | | yy | 44, 01, 00, 17 | - | | yyy | 044, 001, 1900, 2017 | - | | yyyy | 0044, 0001, 1900, 2017 | - | | yyyyy | ... | - | Local week-numbering year | Y | 44, 1, 1900, 2017 | - | | Yo | 44th, 1st, 1900th, 2017th | - | | YY | 44, 01, 00, 17 | - | | YYY | 044, 001, 1900, 2017 | - | | YYYY | 0044, 0001, 1900, 2017 | - | | YYYYY | ... | - | ISO week-numbering year | R | -43, 0, 1, 1900, 2017 | - | | RR | -43, 00, 01, 1900, 2017 | - | | RRR | -043, 000, 001, 1900, 2017 | - | | RRRR | -0043, 0000, 0001, 1900, 2017 | - | | RRRRR | ... | - | Extended year | u | -43, 0, 1, 1900, 2017 | - | | uu | -43, 01, 1900, 2017 | - | | uuu | -043, 001, 1900, 2017 | - | | uuuu | -0043, 0001, 1900, 2017 | - | | uuuuu | ... | - | Quarter (formatting) | Q | 1, 2, 3, 4 | - | | Qo | 1st, 2nd, 3rd, 4th | - | | QQ | 01, 02, 03, 04 | - | | QQQ | Q1, Q2, Q3, Q4 | - | | QQQQ | 1st quarter, 2nd quarter, ... | - | | QQQQQ | 1, 2, 3, 4 | - | Quarter (stand-alone) | q | 1, 2, 3, 4 | - | | qo | 1st, 2nd, 3rd, 4th | - | | qq | 01, 02, 03, 04 | - | | qqq | Q1, Q2, Q3, Q4 | - | | qqqq | 1st quarter, 2nd quarter, ... | - | | qqqqq | 1, 2, 3, 4 | - | Month (formatting) | M | 1, 2, ..., 12 | - | | Mo | 1st, 2nd, ..., 12th | - | | MM | 01, 02, ..., 12 | - | | MMM | Jan, Feb, ..., Dec | - | | MMMM | January, February, ..., December | - | | MMMMM | J, F, ..., D | - | Month (stand-alone) | L | 1, 2, ..., 12 | - | | Lo | 1st, 2nd, ..., 12th | - | | LL | 01, 02, ..., 12 | - | | LLL | Jan, Feb, ..., Dec | - | | LLLL | January, February, ..., December | - | | LLLLL | J, F, ..., D | - | Local week of year | w | 1, 2, ..., 53 | - | | wo | 1st, 2nd, ..., 53th | - | | ww | 01, 02, ..., 53 | - | ISO week of year | I | 1, 2, ..., 53 | - | | Io | 1st, 2nd, ..., 53th | - | | II | 01, 02, ..., 53 | - | Day of month | d | 1, 2, ..., 31 | - | | do | 1st, 2nd, ..., 31st | - | | dd | 01, 02, ..., 31 | - | Day of year | D | 1, 2, ..., 365, 366 | - | | Do | 1st, 2nd, ..., 365th, 366th | - | | DD | 01, 02, ..., 365, 366 | - | | DDD | 001, 002, ..., 365, 366 | - | | DDDD | ... | - | Day of week (formatting) | E..EEE | Mon, Tue, Wed, ..., Su | - | | EEEE | Monday, Tuesday, ..., Sunday | - | | EEEEE | M, T, W, T, F, S, S | - | | EEEEEE | Mo, Tu, We, Th, Fr, Su, Sa | - | ISO day of week (formatting) | i | 1, 2, 3, ..., 7 | - | | io | 1st, 2nd, ..., 7th | - | | ii | 01, 02, ..., 07 | - | | iii | Mon, Tue, Wed, ..., Su | - | | iiii | Monday, Tuesday, ..., Sunday | - | | iiiii | M, T, W, T, F, S, S | - | | iiiiii | Mo, Tu, We, Th, Fr, Su, Sa | - | Local day of week (formatting) | e | 2, 3, 4, ..., 1 | - | | eo | 2nd, 3rd, ..., 1st | - | | ee | 02, 03, ..., 01 | - | | eee | Mon, Tue, Wed, ..., Su | - | | eeee | Monday, Tuesday, ..., Sunday | - | | eeeee | M, T, W, T, F, S, S | - | | eeeeee | Mo, Tu, We, Th, Fr, Su, Sa | - | Local day of week (stand-alone) | c | 2, 3, 4, ..., 1 | - | | co | 2nd, 3rd, ..., 1st | - | | cc | 02, 03, ..., 01 | - | | ccc | Mon, Tue, Wed, ..., Su | - | | cccc | Monday, Tuesday, ..., Sunday | - | | ccccc | M, T, W, T, F, S, S | - | | cccccc | Mo, Tu, We, Th, Fr, Su, Sa | - | AM, PM | a..aaa | AM, PM | - | | aaaa | a.m., p.m. | - | | aaaaa | a, p | - | AM, PM, noon, midnight | b..bbb | AM, PM, noon, midnight | - | | bbbb | a.m., p.m., noon, midnight | - | | bbbbb | a, p, n, mi | - | Flexible day period | B..BBB | at night, in the morning, ... | - | | BBBB | at night, in the morning, ... | - | | BBBBB | at night, in the morning, ... | - | Hour [1-12] | h | 1, 2, ..., 11, 12 | - | | ho | 1st, 2nd, ..., 11th, 12th | - | | hh | 01, 02, ..., 11, 12 | - | Hour [0-23] | H | 0, 1, 2, ..., 23 | - | | Ho | 0th, 1st, 2nd, ..., 23rd | - | | HH | 00, 01, 02, ..., 23 | - | Hour [0-11] | K | 1, 2, ..., 11, 0 | - | | Ko | 1st, 2nd, ..., 11th, 0th | - | | KK | 1, 2, ..., 11, 0 | - | Hour [1-24] | k | 24, 1, 2, ..., 23 | - | | ko | 24th, 1st, 2nd, ..., 23rd | - | | kk | 24, 01, 02, ..., 23 | - | Minute | m | 0, 1, ..., 59 | - | | mo | 0th, 1st, ..., 59th | - | | mm | 00, 01, ..., 59 | - | Second | s | 0, 1, ..., 59 | - | | so | 0th, 1st, ..., 59th | - | | ss | 00, 01, ..., 59 | - | Fraction of second | S | 0, 1, ..., 9 | - | | SS | 00, 01, ..., 99 | - | | SSS | 000, 0001, ..., 999 | - | | SSSS | ... | - | Timezone (ISO-8601 w/ Z) | X | -08, +0530, Z | - | | XX | -0800, +0530, Z | - | | XXX | -08:00, +05:30, Z | - | | XXXX | -0800, +0530, Z, +123456 | - | | XXXXX | -08:00, +05:30, Z, +12:34:56 | - | Timezone (ISO-8601 w/o Z) | x | -08, +0530, +00 | - | | xx | -0800, +0530, +0000 | - | | xxx | -08:00, +05:30, +00:00 | - | | xxxx | -0800, +0530, +0000, +123456 | - | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | - | Timezone (GMT) | O...OOO | GMT-8, GMT+5:30, GMT+0 | - | | OOOO | GMT-08:00, GMT+05:30, GMT+00:00 | - | Timezone (specific non-locat.) | z...zzz | GMT-8, GMT+5:30, GMT+0 | - | | zzzz | GMT-08:00, GMT+05:30, GMT+00:00 | - | Seconds timestamp | t | 512969520 | - | | tt | ... | - | Milliseconds timestamp | T | 512969520900 | - | | TT | ... | - | Long localized date | P | 5/29/53 | - | | PP | May 29, 1453 | - | | PPP | May 29th, 1453 | - | | PPPP | Sunday, May 29th, 1453 | - | Long localized time | p | 12:00 AM | - | | pp | 12:00:00 AM | - | | ppp | 12:00:00 AM GMT+2 | - | | pppp | 12:00:00 AM GMT+02:00 | - | Combination of date and time | Pp | 5/29/53, 12:00 AM | - | | PPpp | May 29, 1453, 12:00 AM | - | | PPPppp | May 29th, 1453 at ... | - | | PPPPpppp| Sunday, May 29th, 1453 at ... | + | Unit | Pattern | Result examples | + | ------------------------------- | -------- | --------------------------------- | + | Era | G..GGG | AD, BC | + | | GGGG | Anno Domini, Before Christ | + | | GGGGG | A, B | + | Calendar year | y | 44, 1, 1900, 2017 | + | | yo | 44th, 1st, 0th, 17th | + | | yy | 44, 01, 00, 17 | + | | yyy | 044, 001, 1900, 2017 | + | | yyyy | 0044, 0001, 1900, 2017 | + | | yyyyy | ... | + | Local week-numbering year | Y | 44, 1, 1900, 2017 | + | | Yo | 44th, 1st, 1900th, 2017th | + | | YY | 44, 01, 00, 17 | + | | YYY | 044, 001, 1900, 2017 | + | | YYYY | 0044, 0001, 1900, 2017 | + | | YYYYY | ... | + | ISO week-numbering year | R | -43, 0, 1, 1900, 2017 | + | | RR | -43, 00, 01, 1900, 2017 | + | | RRR | -043, 000, 001, 1900, 2017 | + | | RRRR | -0043, 0000, 0001, 1900, 2017 | + | | RRRRR | ... | + | Extended year | u | -43, 0, 1, 1900, 2017 | + | | uu | -43, 01, 1900, 2017 | + | | uuu | -043, 001, 1900, 2017 | + | | uuuu | -0043, 0001, 1900, 2017 | + | | uuuuu | ... | + | Quarter (formatting) | Q | 1, 2, 3, 4 | + | | Qo | 1st, 2nd, 3rd, 4th | + | | QQ | 01, 02, 03, 04 | + | | QQQ | Q1, Q2, Q3, Q4 | + | | QQQQ | 1st quarter, 2nd quarter, ... | + | | QQQQQ | 1, 2, 3, 4 | + | Quarter (stand-alone) | q | 1, 2, 3, 4 | + | | qo | 1st, 2nd, 3rd, 4th | + | | qq | 01, 02, 03, 04 | + | | qqq | Q1, Q2, Q3, Q4 | + | | qqqq | 1st quarter, 2nd quarter, ... | + | | qqqqq | 1, 2, 3, 4 | + | Month (formatting) | M | 1, 2, ..., 12 | + | | Mo | 1st, 2nd, ..., 12th | + | | MM | 01, 02, ..., 12 | + | | MMM | Jan, Feb, ..., Dec | + | | MMMM | January, February, ..., December | + | | MMMMM | J, F, ..., D | + | Month (stand-alone) | L | 1, 2, ..., 12 | + | | Lo | 1st, 2nd, ..., 12th | + | | LL | 01, 02, ..., 12 | + | | LLL | Jan, Feb, ..., Dec | + | | LLLL | January, February, ..., December | + | | LLLLL | J, F, ..., D | + | Local week of year | w | 1, 2, ..., 53 | + | | wo | 1st, 2nd, ..., 53th | + | | ww | 01, 02, ..., 53 | + | ISO week of year | I | 1, 2, ..., 53 | + | | Io | 1st, 2nd, ..., 53th | + | | II | 01, 02, ..., 53 | + | Day of month | d | 1, 2, ..., 31 | + | | do | 1st, 2nd, ..., 31st | + | | dd | 01, 02, ..., 31 | + | Day of year | D | 1, 2, ..., 365, 366 | + | | Do | 1st, 2nd, ..., 365th, 366th | + | | DD | 01, 02, ..., 365, 366 | + | | DDD | 001, 002, ..., 365, 366 | + | | DDDD | ... | + | Day of week (formatting) | E..EEE | Mon, Tue, Wed, ..., Su | + | | EEEE | Monday, Tuesday, ..., Sunday | + | | EEEEE | M, T, W, T, F, S, S | + | | EEEEEE | Mo, Tu, We, Th, Fr, Su, Sa | + | ISO day of week (formatting) | i | 1, 2, 3, ..., 7 | + | | io | 1st, 2nd, ..., 7th | + | | ii | 01, 02, ..., 07 | + | | iii | Mon, Tue, Wed, ..., Su | + | | iiii | Monday, Tuesday, ..., Sunday | + | | iiiii | M, T, W, T, F, S, S | + | | iiiiii | Mo, Tu, We, Th, Fr, Su, Sa | + | Local day of week (formatting) | e | 2, 3, 4, ..., 1 | + | | eo | 2nd, 3rd, ..., 1st | + | | ee | 02, 03, ..., 01 | + | | eee | Mon, Tue, Wed, ..., Su | + | | eeee | Monday, Tuesday, ..., Sunday | + | | eeeee | M, T, W, T, F, S, S | + | | eeeeee | Mo, Tu, We, Th, Fr, Su, Sa | + | Local day of week (stand-alone) | c | 2, 3, 4, ..., 1 | + | | co | 2nd, 3rd, ..., 1st | + | | cc | 02, 03, ..., 01 | + | | ccc | Mon, Tue, Wed, ..., Su | + | | cccc | Monday, Tuesday, ..., Sunday | + | | ccccc | M, T, W, T, F, S, S | + | | cccccc | Mo, Tu, We, Th, Fr, Su, Sa | + | AM, PM | a..aaa | AM, PM | + | | aaaa | a.m., p.m. | + | | aaaaa | a, p | + | AM, PM, noon, midnight | b..bbb | AM, PM, noon, midnight | + | | bbbb | a.m., p.m., noon, midnight | + | | bbbbb | a, p, n, mi | + | Flexible day period | B..BBB | at night, in the morning, ... | + | | BBBB | at night, in the morning, ... | + | | BBBBB | at night, in the morning, ... | + | Hour [1-12] | h | 1, 2, ..., 11, 12 | + | | ho | 1st, 2nd, ..., 11th, 12th | + | | hh | 01, 02, ..., 11, 12 | + | Hour [0-23] | H | 0, 1, 2, ..., 23 | + | | Ho | 0th, 1st, 2nd, ..., 23rd | + | | HH | 00, 01, 02, ..., 23 | + | Hour [0-11] | K | 1, 2, ..., 11, 0 | + | | Ko | 1st, 2nd, ..., 11th, 0th | + | | KK | 1, 2, ..., 11, 0 | + | Hour [1-24] | k | 24, 1, 2, ..., 23 | + | | ko | 24th, 1st, 2nd, ..., 23rd | + | | kk | 24, 01, 02, ..., 23 | + | Minute | m | 0, 1, ..., 59 | + | | mo | 0th, 1st, ..., 59th | + | | mm | 00, 01, ..., 59 | + | Second | s | 0, 1, ..., 59 | + | | so | 0th, 1st, ..., 59th | + | | ss | 00, 01, ..., 59 | + | Fraction of second | S | 0, 1, ..., 9 | + | | SS | 00, 01, ..., 99 | + | | SSS | 000, 0001, ..., 999 | + | | SSSS | ... | + | Timezone (ISO-8601 w/ Z) | X | -08, +0530, Z | + | | XX | -0800, +0530, Z | + | | XXX | -08:00, +05:30, Z | + | | XXXX | -0800, +0530, Z, +123456 | + | | XXXXX | -08:00, +05:30, Z, +12:34:56 | + | Timezone (ISO-8601 w/o Z) | x | -08, +0530, +00 | + | | xx | -0800, +0530, +0000 | + | | xxx | -08:00, +05:30, +00:00 | + | | xxxx | -0800, +0530, +0000, +123456 | + | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | + | Timezone (GMT) | O...OOO | GMT-8, GMT+5:30, GMT+0 | + | | OOOO | GMT-08:00, GMT+05:30, GMT+00:00 | + | Timezone (specific non-locat.) | z...zzz | GMT-8, GMT+5:30, GMT+0 | + | | zzzz | GMT-08:00, GMT+05:30, GMT+00:00 | + | Seconds timestamp | t | 512969520 | + | | tt | ... | + | Milliseconds timestamp | T | 512969520900 | + | | TT | ... | + | Long localized date | P | 5/29/53 | + | | PP | May 29, 1453 | + | | PPP | May 29th, 1453 | + | | PPPP | Sunday, May 29th, 1453 | + | Long localized time | p | 12:00 AM | + | | pp | 12:00:00 AM | + | | ppp | 12:00:00 AM GMT+2 | + | | pppp | 12:00:00 AM GMT+02:00 | + | Combination of date and time | Pp | 5/29/53, 12:00 AM | + | | PPpp | May 29, 1453, 12:00 AM | + | | PPPppp | May 29th, 1453 at ... | + | | PPPPpppp | Sunday, May 29th, 1453 at ... | Characters are now escaped using single quote symbols (`'`) instead of square brackets. `format` now throws RangeError if it encounters an unescaped latin character @@ -375,20 +388,25 @@ for the list of changes made since `v2.0.0-alpha.1`. // Before v2.0.0 areRangesOverlapping( - new Date(2014, 0, 10), new Date(2014, 0, 20), - new Date(2014, 0, 17), new Date(2014, 0, 21) + new Date(2014, 0, 10), + new Date(2014, 0, 20), + new Date(2014, 0, 17), + new Date(2014, 0, 21) ) eachDay(new Date(2014, 0, 10), new Date(2014, 0, 20)) getOverlappingDaysInRanges( - new Date(2014, 0, 10), new Date(2014, 0, 20), - new Date(2014, 0, 17), new Date(2014, 0, 21) + new Date(2014, 0, 10), + new Date(2014, 0, 20), + new Date(2014, 0, 17), + new Date(2014, 0, 21) ) isWithinRange( new Date(2014, 0, 3), - new Date(2014, 0, 1), new Date(2014, 0, 7) + new Date(2014, 0, 1), + new Date(2014, 0, 7) ) // v2.0.0 onward @@ -398,19 +416,20 @@ for the list of changes made since `v2.0.0-alpha.1`. { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) } ) - eachDayOfInterval( - { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) } - ) + eachDayOfInterval({ + start: new Date(2014, 0, 10), + end: new Date(2014, 0, 20) + }) getOverlappingDaysInIntervals( { start: new Date(2014, 0, 10), end: new Date(2014, 0, 20) }, { start: new Date(2014, 0, 17), end: new Date(2014, 0, 21) } ) - isWithinInterval( - new Date(2014, 0, 3), - { start: new Date(2014, 0, 1), end: new Date(2014, 0, 7) } - ) + isWithinInterval(new Date(2014, 0, 3), { + start: new Date(2014, 0, 1), + end: new Date(2014, 0, 7) + }) ``` - **BREAKING**: functions renamed: @@ -533,20 +552,20 @@ for the list of changes made since `v2.0.0-alpha.1`. Examples: | `isValid` argument | Before v2.0.0 | v2.0.0 onward | - |---------------------------|---------------|---------------| + | ------------------------- | ------------- | ------------- | | `new Date()` | `true` | `true` | | `new Date('2016-01-01')` | `true` | `true` | | `new Date('')` | `false` | `false` | | `new Date(1488370835081)` | `true` | `true` | | `new Date(NaN)` | `false` | `false` | - | `'2016-01-01'` | `TypeError` | `false` | + | `'2016-01-01'` | `TypeError` | `false` | | `''` | `TypeError` | `false` | | `1488370835081` | `TypeError` | `true` | | `NaN` | `TypeError` | `false` | - We introduce this change to make *date-fns* consistent with ECMAScript behavior + We introduce this change to make _date-fns_ consistent with ECMAScript behavior that try to coerce arguments to the expected type - (which is also the case with other *date-fns* functions). + (which is also the case with other _date-fns_ functions). - **BREAKING**: functions now throw `RangeError` if optional values passed to `options` are not `undefined` or have expected values. @@ -559,20 +578,21 @@ for the list of changes made since `v2.0.0-alpha.1`. - **BREAKING**: all functions now implicitly convert arguments by following rules: - | | date | number | string | boolean | - |-----------|---------------|--------|-------------|---------| - | 0 | new Date(0) | 0 | '0' | false | - | '0' | Invalid Date | 0 | '0' | false | - | 1 | new Date(1) | 1 | '1' | true | - | '1' | Invalid Date | 1 | '1' | true | - | true | Invalid Date | NaN | 'true' | true | - | false | Invalid Date | NaN | 'false' | false | - | null | Invalid Date | NaN | 'null' | false | - | undefined | Invalid Date | NaN | 'undefined' | false | - | NaN | Invalid Date | NaN | 'NaN' | false | + | | date | number | string | boolean | + | --------- | ------------ | ------ | ----------- | ------- | + | 0 | new Date(0) | 0 | '0' | false | + | '0' | Invalid Date | 0 | '0' | false | + | 1 | new Date(1) | 1 | '1' | true | + | '1' | Invalid Date | 1 | '1' | true | + | true | Invalid Date | NaN | 'true' | true | + | false | Invalid Date | NaN | 'false' | false | + | null | Invalid Date | NaN | 'null' | false | + | undefined | Invalid Date | NaN | 'undefined' | false | + | NaN | Invalid Date | NaN | 'NaN' | false | Notes: - - as before, arguments expected to be `Date` are converted to `Date` using *date-fns'* `toDate` function; + + - as before, arguments expected to be `Date` are converted to `Date` using _date-fns'_ `toDate` function; - arguments expected to be numbers are converted to integer numbers using our custom `toInteger` implementation (see [#765](https://github.com/date-fns/date-fns/pull/765)); - arguments expected to be strings are converted to strings using JavaScript's `String` function; @@ -629,7 +649,7 @@ for the list of changes made since `v2.0.0-alpha.1`. const addFiveYears = addYears(5) // Several arguments can be curried at once - const dateToString = formatWithOptions({locale: eo}, 'd MMMM yyyy') + const dateToString = formatWithOptions({ locale: eo }, 'd MMMM yyyy') const dates = [ new Date(2017, 0 /* Jan */, 1), @@ -637,7 +657,7 @@ for the list of changes made since `v2.0.0-alpha.1`. new Date(2017, 6 /* Jul */, 2) ] - const formattedDates = dates.map((date) => dateToString(addFiveYears(date))) + const formattedDates = dates.map(date => dateToString(addFiveYears(date))) //=> ['1 januaro 2022', '11 februaro 2022', '2 julio 2022'] ``` @@ -703,11 +723,11 @@ for the list of changes made since `v2.0.0-alpha.1`. - New interval, month, and year helpers to fetch a list of all Saturdays and Sundays (weekends) for a given date interval. `eachWeekendOfInterval` is the handler function while the other two are wrapper functions. Kudos to [@laekettavong](https://github.com/laekettavong)! - - `eachWeekendOfInterval` + - `eachWeekendOfInterval` - - `eachWeekendOfMonth` + - `eachWeekendOfMonth` - - `eachWeekendOfYear` + - `eachWeekendOfYear` - Build-efficient `lightFormat` that only supports the popular subset of tokens. See [#1050](https://github.com/date-fns/date-fns/pull/1015). @@ -739,7 +759,7 @@ for the list of changes made since `v2.0.0-alpha.1`. - [Bengali locale (bb)](https://github.com/date-fns/date-fns/pull/845) by [@nutboltu](https://github.com/nutboltu) and [@touhidrahman](https://github.com/touhidrahman). - - [Hungarian (hu) and Lithuanian (lt) locales](https://github.com/date-fns/date-fns/pull/864) + - [Hungarian (hu) and Lithuanian (lt) locales](https://github.com/date-fns/date-fns/pull/864) by [@izifortune](https://github.com/izifortune) and [pardoeryanair](https://github.com/pardoeryanair). - [Canadian English locale (en-CA)](https://github.com/date-fns/date-fns/pull/688) @@ -1028,7 +1048,7 @@ for the list of changes made since `v2.0.0-alpha.1`. check if the passed locale is valid, and fallback to English locale otherwise. See PR: [#321](https://github.com/date-fns/date-fns/pull/321) -- *Internal*: use a loop instead of `Object.keys` in `buildFormattingTokensRegExp` +- _Internal_: use a loop instead of `Object.keys` in `buildFormattingTokensRegExp` to improve compatibility with older browsers. See PR: [#322](https://github.com/date-fns/date-fns/pull/322) @@ -1152,8 +1172,8 @@ for the list of changes made since `v2.0.0-alpha.1`. ```javascript parse('+002016-11-01') - parse('+02016-11-01', {additionalDigits: 1}) - parse('+2016-11-01', {additionalDigits: 0}) + parse('+02016-11-01', { additionalDigits: 1 }) + parse('+2016-11-01', { additionalDigits: 0 }) ``` ## [1.9.0] - 2016-10-25 @@ -1294,7 +1314,7 @@ for the list of changes made since `v2.0.0-alpha.1`. var result = endOfWeek(new Date(2014, 8, 2), 1) // v1.0.0 onward - var result = endOfWeek(new Date(2014, 8, 2), {weekStartsOn: 1}) + var result = endOfWeek(new Date(2014, 8, 2), { weekStartsOn: 1 }) ``` - **BREAKING**: remove the function `getTimeSinceMidnight` that was used inside @@ -1308,9 +1328,9 @@ for the list of changes made since `v2.0.0-alpha.1`. - Faster `isLeapYear`. -- *Internal*: make the documentation more verbose. +- _Internal_: make the documentation more verbose. -- *Internal*: convert the tests from Chai to power-assert allowing them +- _Internal_: convert the tests from Chai to power-assert allowing them to run against IE8. ### Added @@ -1441,7 +1461,7 @@ for the list of changes made since `v2.0.0-alpha.1`. - `setISOWeek` now keeps time from original date. -- *Internal*: reuse `getDaysInMonth` inside of `addMonths`. +- _Internal_: reuse `getDaysInMonth` inside of `addMonths`. ### Added @@ -1463,7 +1483,7 @@ for the list of changes made since `v2.0.0-alpha.1`. - `parse` now fallbacks to `new Date` when the argument is not an ISO formatted date. -- *Internal*: reuse `getDaysInMonth` inside of `setMonth`. +- _Internal_: reuse `getDaysInMonth` inside of `setMonth`. ### Added @@ -1538,9 +1558,9 @@ for the list of changes made since `v2.0.0-alpha.1`. - `setMonth` now sets last day of month if original date was last day of longer month. -- *Internal*: Fix code style according to ESLint. +- _Internal_: Fix code style according to ESLint. -- *Internal*: Make tests run through all time zones. +- _Internal_: Make tests run through all time zones. ### Added @@ -1691,7 +1711,7 @@ for the list of changes made since `v2.0.0-alpha.1`. ### Changed -- *Internal*: simplify `isWeekend` +- _Internal_: simplify `isWeekend` ### Added @@ -1701,7 +1721,7 @@ for the list of changes made since `v2.0.0-alpha.1`. ### Changed -- *Internal*: reuse `addDays` inside of `subDays`. +- _Internal_: reuse `addDays` inside of `subDays`. ### Added @@ -1779,7 +1799,7 @@ for the list of changes made since `v2.0.0-alpha.1`. - `startOfDay` -[Unreleased]: https://github.com/date-fns/date-fns/compare/v1.28.5...HEAD +[unreleased]: https://github.com/date-fns/date-fns/compare/v1.28.5...HEAD [1.28.5]: https://github.com/date-fns/date-fns/compare/v1.28.4...v1.28.5 [1.28.4]: https://github.com/date-fns/date-fns/compare/v1.28.3...v1.28.4 [1.28.3]: https://github.com/date-fns/date-fns/compare/v1.28.2...v1.28.3 diff --git a/src/differenceInBusinessDays/index.d.ts b/src/differenceInBusinessDays/index.d.ts new file mode 100644 index 0000000000..8decd89c3f --- /dev/null +++ b/src/differenceInBusinessDays/index.d.ts @@ -0,0 +1,4 @@ +// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it. + +import { differenceInBusinessDays } from 'date-fns' +export default differenceInBusinessDays diff --git a/src/differenceInBusinessDays/index.js b/src/differenceInBusinessDays/index.js new file mode 100644 index 0000000000..733a1d2790 --- /dev/null +++ b/src/differenceInBusinessDays/index.js @@ -0,0 +1,50 @@ +import toDate from '../toDate/index.js' +import eachDayOfInterval from '../eachDayOfInterval/index.js' +import isWeekend from '../isWeekend/index.js' + +/** + * @name differenceInBusinessDays + * @category Day Helpers + * @summary Get the number of business days between the given dates. + * + * @description + * Get the number of business day periods between the given dates. + * Business days being days that arent in the weekend. + * + * @param {Date|Number} dateLeft - the later date + * @param {Date|Number} dateRight - the earlier date + * @returns {Number} the number of business days + * @throws {TypeError} 2 arguments required + * + * @example + * // How many business days are between + * // 10 Januari 2014 and 20 July 2014? + * var result = differenceInBusinessDays( + * new Date(2014, 0, 10) + * new Date(2014, 6, 20), + * ) + * //=> 136 + */ +export default function differenceInBusinessDays( + dirtyDateLeft, + dirtyDateRight +) { + if (arguments.length < 2) { + throw new TypeError( + '2 arguments required, but only ' + arguments.length + ' present' + ) + } + + var dateLeft = toDate(dirtyDateLeft) + var dateRight = toDate(dirtyDateRight) + var interval = { start: dateLeft, end: dateRight } + + var daysOfInterval = eachDayOfInterval(interval) + var difference = daysOfInterval.filter(function(day) { + return !isWeekend(toDate(day)) + }) + var result = difference.length + + // Prevent negative zero + return difference.length === 0 ? 0 : difference.length +} diff --git a/src/differenceInBusinessDays/index.js.flow b/src/differenceInBusinessDays/index.js.flow new file mode 100644 index 0000000000..117ab722a3 --- /dev/null +++ b/src/differenceInBusinessDays/index.js.flow @@ -0,0 +1,41 @@ +// @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: ( + dateLeft: Date | number, + dateRight: Date | number +) => number diff --git a/src/differenceInBusinessDays/test.js b/src/differenceInBusinessDays/test.js new file mode 100644 index 0000000000..aa043cdd63 --- /dev/null +++ b/src/differenceInBusinessDays/test.js @@ -0,0 +1,49 @@ +// @flow +/* eslint-env mocha */ + +import assert from 'power-assert' +import differenceInBusinessDays from '.' + +describe('differenceInBusinessDays', function() { + it('returns the number of business days between the given dates, excluding weekends', function() { + var result = differenceInBusinessDays( + new Date(2014, 0 /* Jan */, 10), + new Date(2014, 6 /* Jul */, 20) + ) + assert(result === 136) + }) + + it('accepts timestamps', function() { + var result = differenceInBusinessDays( + new Date(2014, 0, 10).getTime(), + new Date(2014, 6, 20).getTime() + ) + assert(result === 136) + }) + + describe('edge cases', function() { + it('counts endDate, even when date is the same', function() { + var result = differenceInBusinessDays( + new Date(2014, 8 /* Sep */, 5, 0, 0), + new Date(2014, 8 /* Sep */, 5, 0, 0) + ) + assert(result === 1) + }) + + it('throws RangeError when start date is after end date', function() { + assert.throws( + differenceInBusinessDays.bind( + null, + new Date(2014, 6, 20).getTime(), + new Date(2014, 0, 10).getTime() + ), + RangeError + ) + }) + }) + + it('throws TypeError exception if passed less than 2 arguments', function() { + assert.throws(differenceInBusinessDays.bind(null), TypeError) + assert.throws(differenceInBusinessDays.bind(null, 1), TypeError) + }) +}) diff --git a/src/esm/fp/index.js b/src/esm/fp/index.js index 4c0d54d093..2d6a5016ee 100644 --- a/src/esm/fp/index.js +++ b/src/esm/fp/index.js @@ -17,6 +17,9 @@ export { default as closestIndexTo } from './closestIndexTo/index.js' export { default as closestTo } from './closestTo/index.js' export { default as compareAsc } from './compareAsc/index.js' export { default as compareDesc } from './compareDesc/index.js' +export { + default as differenceInBusinessDays +} from './differenceInBusinessDays/index.js' export { default as differenceInCalendarDays } from './differenceInCalendarDays/index.js' diff --git a/src/esm/index.js b/src/esm/index.js index 99a8526395..4f2c2ed493 100644 --- a/src/esm/index.js +++ b/src/esm/index.js @@ -17,6 +17,9 @@ export { default as closestIndexTo } from './closestIndexTo/index.js' export { default as closestTo } from './closestTo/index.js' export { default as compareAsc } from './compareAsc/index.js' export { default as compareDesc } from './compareDesc/index.js' +export { + default as differenceInBusinessDays +} from './differenceInBusinessDays/index.js' export { default as differenceInCalendarDays } from './differenceInCalendarDays/index.js' diff --git a/src/fp/differenceInBusinessDays/index.d.ts b/src/fp/differenceInBusinessDays/index.d.ts new file mode 100644 index 0000000000..4ff989062a --- /dev/null +++ b/src/fp/differenceInBusinessDays/index.d.ts @@ -0,0 +1,4 @@ +// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it. + +import { differenceInBusinessDays } from 'date-fns/fp' +export default differenceInBusinessDays diff --git a/src/fp/differenceInBusinessDays/index.js b/src/fp/differenceInBusinessDays/index.js new file mode 100644 index 0000000000..c019a5b266 --- /dev/null +++ b/src/fp/differenceInBusinessDays/index.js @@ -0,0 +1,8 @@ +// This file is generated automatically by `scripts/build/fp.js`. Please, don't change it. + +import fn from '../../differenceInBusinessDays/index.js' +import convertToFP from '../_lib/convertToFP/index.js' + +var differenceInBusinessDays = convertToFP(fn, 2) + +export default differenceInBusinessDays diff --git a/src/fp/differenceInBusinessDays/index.js.flow b/src/fp/differenceInBusinessDays/index.js.flow new file mode 100644 index 0000000000..82c037fce2 --- /dev/null +++ b/src/fp/differenceInBusinessDays/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: A) => R + +type CurriedFn2 = ( + a: A +) => CurriedFn1 | ((a: A, b: B) => R) + +declare module.exports: CurriedFn2 diff --git a/src/fp/index.js b/src/fp/index.js index 4b3752748b..261e022c14 100644 --- a/src/fp/index.js +++ b/src/fp/index.js @@ -18,6 +18,7 @@ module.exports = { closestTo: require('./closestTo/index.js'), compareAsc: require('./compareAsc/index.js'), compareDesc: require('./compareDesc/index.js'), + differenceInBusinessDays: require('./differenceInBusinessDays/index.js'), differenceInCalendarDays: require('./differenceInCalendarDays/index.js'), differenceInCalendarISOWeekYears: require('./differenceInCalendarISOWeekYears/index.js'), differenceInCalendarISOWeeks: require('./differenceInCalendarISOWeeks/index.js'), diff --git a/src/fp/index.js.flow b/src/fp/index.js.flow index 711877e5f0..4fd6141bf9 100644 --- a/src/fp/index.js.flow +++ b/src/fp/index.js.flow @@ -81,6 +81,7 @@ declare module.exports: { closestTo: CurriedFn2<(Date | number)[], Date | number, Date>, compareAsc: CurriedFn2, compareDesc: CurriedFn2, + differenceInBusinessDays: CurriedFn2, differenceInCalendarDays: CurriedFn2, differenceInCalendarISOWeeks: CurriedFn2< Date | number, diff --git a/src/index.js b/src/index.js index 049ad813c7..2ae1382dae 100644 --- a/src/index.js +++ b/src/index.js @@ -18,6 +18,7 @@ module.exports = { closestTo: require('./closestTo/index.js'), compareAsc: require('./compareAsc/index.js'), compareDesc: require('./compareDesc/index.js'), + differenceInBusinessDays: require('./differenceInBusinessDays/index.js'), differenceInCalendarDays: require('./differenceInCalendarDays/index.js'), differenceInCalendarISOWeekYears: require('./differenceInCalendarISOWeekYears/index.js'), differenceInCalendarISOWeeks: require('./differenceInCalendarISOWeeks/index.js'), diff --git a/src/index.js.flow b/src/index.js.flow index 5546e430d9..53f5aaf286 100644 --- a/src/index.js.flow +++ b/src/index.js.flow @@ -75,6 +75,11 @@ declare module.exports: { compareDesc: (dateLeft: Date | number, dateRight: Date | number) => number, + differenceInBusinessDays: ( + dateLeft: Date | number, + dateRight: Date | number + ) => number, + differenceInCalendarDays: ( dateLeft: Date | number, dateRight: Date | number diff --git a/typings.d.ts b/typings.d.ts index d2cd4437dd..1318494fe0 100644 --- a/typings.d.ts +++ b/typings.d.ts @@ -130,6 +130,12 @@ declare module 'date-fns' { ): number namespace compareDesc {} + function differenceInBusinessDays( + dateLeft: Date | number, + dateRight: Date | number + ): number + namespace differenceInBusinessDays {} + function differenceInCalendarDays( dateLeft: Date | number, dateRight: Date | number @@ -869,6 +875,11 @@ declare module 'date-fns/compareDesc' { export default compareDesc } +declare module 'date-fns/differenceInBusinessDays' { + import { differenceInBusinessDays } from 'date-fns' + export default differenceInBusinessDays +} + declare module 'date-fns/differenceInCalendarDays' { import { differenceInCalendarDays } from 'date-fns' export default differenceInCalendarDays @@ -1644,6 +1655,11 @@ declare module 'date-fns/compareDesc/index' { export default compareDesc } +declare module 'date-fns/differenceInBusinessDays/index' { + import { differenceInBusinessDays } from 'date-fns' + export default differenceInBusinessDays +} + declare module 'date-fns/differenceInCalendarDays/index' { import { differenceInCalendarDays } from 'date-fns' export default differenceInCalendarDays @@ -2419,6 +2435,11 @@ declare module 'date-fns/compareDesc/index.js' { export default compareDesc } +declare module 'date-fns/differenceInBusinessDays/index.js' { + import { differenceInBusinessDays } from 'date-fns' + export default differenceInBusinessDays +} + declare module 'date-fns/differenceInCalendarDays/index.js' { import { differenceInCalendarDays } from 'date-fns' export default differenceInCalendarDays @@ -3167,6 +3188,13 @@ declare module 'date-fns/fp' { const compareDesc: CurriedFn2 namespace compareDesc {} + const differenceInBusinessDays: CurriedFn2< + Date | number, + Date | number, + number + > + namespace differenceInBusinessDays {} + const differenceInCalendarDays: CurriedFn2< Date | number, Date | number, @@ -3810,6 +3838,11 @@ declare module 'date-fns/fp/compareDesc' { export = compareDesc } +declare module 'date-fns/fp/differenceInBusinessDays' { + import { differenceInBusinessDays } from 'date-fns/fp' + export = differenceInBusinessDays +} + declare module 'date-fns/fp/differenceInCalendarDays' { import { differenceInCalendarDays } from 'date-fns/fp' export = differenceInCalendarDays @@ -4705,6 +4738,11 @@ declare module 'date-fns/fp/compareDesc/index' { export = compareDesc } +declare module 'date-fns/fp/differenceInBusinessDays/index' { + import { differenceInBusinessDays } from 'date-fns/fp' + export = differenceInBusinessDays +} + declare module 'date-fns/fp/differenceInCalendarDays/index' { import { differenceInCalendarDays } from 'date-fns/fp' export = differenceInCalendarDays @@ -5600,6 +5638,11 @@ declare module 'date-fns/fp/compareDesc/index.js' { export = compareDesc } +declare module 'date-fns/fp/differenceInBusinessDays/index.js' { + import { differenceInBusinessDays } from 'date-fns/fp' + export = differenceInBusinessDays +} + declare module 'date-fns/fp/differenceInCalendarDays/index.js' { import { differenceInCalendarDays } from 'date-fns/fp' export = differenceInCalendarDays @@ -6480,6 +6523,12 @@ declare module 'date-fns/esm' { ): number namespace compareDesc {} + function differenceInBusinessDays( + dateLeft: Date | number, + dateRight: Date | number + ): number + namespace differenceInBusinessDays {} + function differenceInCalendarDays( dateLeft: Date | number, dateRight: Date | number @@ -7219,6 +7268,11 @@ declare module 'date-fns/esm/compareDesc' { export default compareDesc } +declare module 'date-fns/esm/differenceInBusinessDays' { + import { differenceInBusinessDays } from 'date-fns/esm' + export default differenceInBusinessDays +} + declare module 'date-fns/esm/differenceInCalendarDays' { import { differenceInCalendarDays } from 'date-fns/esm' export default differenceInCalendarDays @@ -7994,6 +8048,11 @@ declare module 'date-fns/esm/compareDesc/index' { export default compareDesc } +declare module 'date-fns/esm/differenceInBusinessDays/index' { + import { differenceInBusinessDays } from 'date-fns/esm' + export default differenceInBusinessDays +} + declare module 'date-fns/esm/differenceInCalendarDays/index' { import { differenceInCalendarDays } from 'date-fns/esm' export default differenceInCalendarDays @@ -8769,6 +8828,11 @@ declare module 'date-fns/esm/compareDesc/index.js' { export default compareDesc } +declare module 'date-fns/esm/differenceInBusinessDays/index.js' { + import { differenceInBusinessDays } from 'date-fns/esm' + export default differenceInBusinessDays +} + declare module 'date-fns/esm/differenceInCalendarDays/index.js' { import { differenceInCalendarDays } from 'date-fns/esm' export default differenceInCalendarDays @@ -9517,6 +9581,13 @@ declare module 'date-fns/esm/fp' { const compareDesc: CurriedFn2 namespace compareDesc {} + const differenceInBusinessDays: CurriedFn2< + Date | number, + Date | number, + number + > + namespace differenceInBusinessDays {} + const differenceInCalendarDays: CurriedFn2< Date | number, Date | number, @@ -10160,6 +10231,11 @@ declare module 'date-fns/esm/fp/compareDesc' { export default compareDesc } +declare module 'date-fns/esm/fp/differenceInBusinessDays' { + import { differenceInBusinessDays } from 'date-fns/esm/fp' + export default differenceInBusinessDays +} + declare module 'date-fns/esm/fp/differenceInCalendarDays' { import { differenceInCalendarDays } from 'date-fns/esm/fp' export default differenceInCalendarDays @@ -11055,6 +11131,11 @@ declare module 'date-fns/esm/fp/compareDesc/index' { export default compareDesc } +declare module 'date-fns/esm/fp/differenceInBusinessDays/index' { + import { differenceInBusinessDays } from 'date-fns/esm/fp' + export default differenceInBusinessDays +} + declare module 'date-fns/esm/fp/differenceInCalendarDays/index' { import { differenceInCalendarDays } from 'date-fns/esm/fp' export default differenceInCalendarDays @@ -11950,6 +12031,11 @@ declare module 'date-fns/esm/fp/compareDesc/index.js' { export default compareDesc } +declare module 'date-fns/esm/fp/differenceInBusinessDays/index.js' { + import { differenceInBusinessDays } from 'date-fns/esm/fp' + export default differenceInBusinessDays +} + declare module 'date-fns/esm/fp/differenceInCalendarDays/index.js' { import { differenceInCalendarDays } from 'date-fns/esm/fp' export default differenceInCalendarDays @@ -14869,6 +14955,11 @@ interface dateFns { compareDesc(dateLeft: Date | number, dateRight: Date | number): number + differenceInBusinessDays( + dateLeft: Date | number, + dateRight: Date | number + ): number + differenceInCalendarDays( dateLeft: Date | number, dateRight: Date | number