diff --git a/src/index.d.ts b/src/index.d.ts index 5d3bb14a31..16ec3d2543 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -160,6 +160,11 @@ declare namespace RamdaAdjunct { */ isDate(val: any): val is Date; + /** + * Checks if value is valid `Date` object. + */ + isValidDate(val: any): val is Date; + /** * Checks if value is complement of `Date` object */ diff --git a/src/index.js b/src/index.js index 2d75f58a74..64ce521a15 100644 --- a/src/index.js +++ b/src/index.js @@ -26,6 +26,7 @@ import isNotObjLike from './isNotObjLike'; import isPlainObj from './isPlainObj'; import isNotPlainObj from './isNotPlainObj'; import isDate from './isDate'; +import isValidDate from './isValidDate'; import isNotDate from './isNotDate'; import isNumber from './isNumber'; import isNotNumber from './isNotNumber'; @@ -89,6 +90,7 @@ export { default as isPlainObject } from './isPlainObj'; export { default as isNotPlainObj } from './isNotPlainObj'; export { default as isNotPlainObject } from './isNotPlainObj'; // alias of isNotPlainObject export { default as isDate } from './isDate'; +export { default as isValidDate} from './isValidDate'; export { default as isNotDate } from './isNotDate'; export { default as isNumber } from './isNumber'; export { default as isNotNumber } from './isNotNumber'; @@ -157,6 +159,7 @@ const RA = { isNotPlainObj, isNotPlainObject: isNotPlainObj, isDate, + isValidDate, isNotDate, isNumber, isNotNumber, diff --git a/src/isValidDate.js b/src/isValidDate.js new file mode 100644 index 0000000000..3617de8565 --- /dev/null +++ b/src/isValidDate.js @@ -0,0 +1,24 @@ +import { invoker, both, pipe } from 'ramda'; + +import isDate from './isDate'; +import isNotNaN from './isNotNaN'; + +/** + * Checks if value is valid `Date` object. + * + * @func isValidDate + * @memberOf RA + * @since {@link https://char0n.github.io/ramda-adjunct/1.8.0|v1.8.0} + * @category Type + * @sig * -> Boolean + * @param {*} val The value to test + * @return {Boolean} + * @see {@link RA.isDate|isDate} + * @example + * + * RA.isValidDate(new Date()); //=> true + * RA.isValidDate(new Date('a')); //=> false + */ +const isValidDate = both(isDate, pipe(invoker(0, 'getTime'), isNotNaN)); + +export default isValidDate; diff --git a/test/isValidDate.js b/test/isValidDate.js new file mode 100644 index 0000000000..26a2f945ab --- /dev/null +++ b/test/isValidDate.js @@ -0,0 +1,30 @@ +import RA from '../src/index'; +import eq from './shared/eq'; +import args from './shared/arguments'; +import Symbol from './shared/Symbol'; + +describe('isValidDate', function() { + it('tests a value for a valid `Date`', function() { + eq(RA.isValidDate(new Date()), true); + + eq(RA.isValidDate(new Date('a')), false); + eq(RA.isValidDate(Date.now()), false); + eq(RA.isValidDate(args), false); + eq(RA.isValidDate([1, 2, 3]), false); + eq(RA.isValidDate(Object(false)), false); + eq(RA.isValidDate(new Error()), false); + eq(RA.isValidDate(RA), false); + eq(RA.isValidDate(Array.prototype.slice), false); + eq(RA.isValidDate({ a: 1 }), false); + eq(RA.isValidDate(Object(0)), false); + eq(RA.isValidDate(/x/), false); + eq(RA.isValidDate(Object('a')), false); + + if (Symbol !== 'undefined') { + eq(RA.isValidDate(Symbol), false); + } + + eq(RA.isValidDate(null), false); + eq(RA.isValidDate(undefined), false); + }); +});