diff options
author | Sebastian <sebasjm@gmail.com> | 2021-08-23 16:46:06 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2021-08-23 16:48:30 -0300 |
commit | 38acabfa6089ab8ac469c12b5f55022fb96935e5 (patch) | |
tree | 453dbf70000cc5e338b06201af1eaca8343f8f73 /date-fns/src/parseISO | |
parent | f26125e039143b92dc0d84e7775f508ab0cdcaa8 (diff) | |
download | node-vendor-master.tar.gz node-vendor-master.tar.bz2 node-vendor-master.zip |
Diffstat (limited to 'date-fns/src/parseISO')
-rw-r--r-- | date-fns/src/parseISO/benchmark.js | 16 | ||||
-rw-r--r-- | date-fns/src/parseISO/index.d.ts | 4 | ||||
-rw-r--r-- | date-fns/src/parseISO/index.js | 343 | ||||
-rw-r--r-- | date-fns/src/parseISO/index.js.flow | 57 | ||||
-rw-r--r-- | date-fns/src/parseISO/test.js | 452 |
5 files changed, 872 insertions, 0 deletions
diff --git a/date-fns/src/parseISO/benchmark.js b/date-fns/src/parseISO/benchmark.js new file mode 100644 index 0000000..19405ed --- /dev/null +++ b/date-fns/src/parseISO/benchmark.js @@ -0,0 +1,16 @@ +// @flow +/* eslint-env mocha */ +/* global suite, benchmark */ + +import parseISO from '.' +import moment from 'moment' + +suite('toDate', function() { + benchmark('date-fns', function() { + return parseISO('2014-10-25T13:46:20+07:00') + }) + + benchmark('Moment.js', function() { + return moment('2014-10-25T13:46:20+07:00') + }) +}) diff --git a/date-fns/src/parseISO/index.d.ts b/date-fns/src/parseISO/index.d.ts new file mode 100644 index 0000000..ee06fe6 --- /dev/null +++ b/date-fns/src/parseISO/index.d.ts @@ -0,0 +1,4 @@ +// This file is generated automatically by `scripts/build/typings.js`. Please, don't change it. + +import { parseISO } from 'date-fns' +export default parseISO diff --git a/date-fns/src/parseISO/index.js b/date-fns/src/parseISO/index.js new file mode 100644 index 0000000..4d4a0af --- /dev/null +++ b/date-fns/src/parseISO/index.js @@ -0,0 +1,343 @@ +import toInteger from '../_lib/toInteger/index' +import requiredArgs from '../_lib/requiredArgs/index' + +var MILLISECONDS_IN_HOUR = 3600000 +var MILLISECONDS_IN_MINUTE = 60000 +var DEFAULT_ADDITIONAL_DIGITS = 2 + +var patterns = { + dateTimeDelimiter: /[T ]/, + timeZoneDelimiter: /[Z ]/i, + timezone: /([Z+-].*)$/, +} + +var dateRegex = /^-?(?:(\d{3})|(\d{2})(?:-?(\d{2}))?|W(\d{2})(?:-?(\d{1}))?|)$/ +var timeRegex = /^(\d{2}(?:[.,]\d*)?)(?::?(\d{2}(?:[.,]\d*)?))?(?::?(\d{2}(?:[.,]\d*)?))?$/ +var timezoneRegex = /^([+-])(\d{2})(?::?(\d{2}))?$/ + +/** + * @name parseISO + * @category Common Helpers + * @summary Parse ISO string + * + * @description + * Parse the given string in ISO 8601 format and return an instance of Date. + * + * Function accepts complete ISO 8601 formats as well as partial implementations. + * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601 + * + * If the argument isn't a string, the function cannot parse the string or + * the values are invalid, it returns Invalid Date. + * + * ### v2.0.0 breaking changes: + * + * - [Changes that are common for the whole library](https://github.com/date-fns/date-fns/blob/master/docs/upgradeGuide.md#Common-Changes). + * + * - The previous `parse` implementation was renamed to `parseISO`. + * + * ```javascript + * // Before v2.0.0 + * parse('2016-01-01') + * + * // v2.0.0 onward + * parseISO('2016-01-01') + * ``` + * + * - `parseISO` now validates separate date and time values in ISO-8601 strings + * and returns `Invalid Date` if the date is invalid. + * + * ```javascript + * parseISO('2018-13-32') + * //=> Invalid Date + * ``` + * + * - `parseISO` now doesn't fall back to `new Date` constructor + * if it fails to parse a string argument. Instead, it returns `Invalid Date`. + * + * @param {String} argument - the value to convert + * @param {Object} [options] - an object with options. + * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format + * @returns {Date} the parsed date in the local time zone + * @throws {TypeError} 1 argument required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Convert string '2014-02-11T11:30:30' to date: + * var result = parseISO('2014-02-11T11:30:30') + * //=> Tue Feb 11 2014 11:30:30 + * + * @example + * // Convert string '+02014101' to date, + * // if the additional number of digits in the extended year format is 1: + * var result = parseISO('+02014101', { additionalDigits: 1 }) + * //=> Fri Apr 11 2014 00:00:00 + */ +export default function parseISO(argument, dirtyOptions) { + requiredArgs(1, arguments) + + var options = dirtyOptions || {} + + var additionalDigits = + options.additionalDigits == null + ? DEFAULT_ADDITIONAL_DIGITS + : toInteger(options.additionalDigits) + if ( + additionalDigits !== 2 && + additionalDigits !== 1 && + additionalDigits !== 0 + ) { + throw new RangeError('additionalDigits must be 0, 1 or 2') + } + + if ( + !( + typeof argument === 'string' || + Object.prototype.toString.call(argument) === '[object String]' + ) + ) { + return new Date(NaN) + } + + var dateStrings = splitDateString(argument) + + var date + if (dateStrings.date) { + var parseYearResult = parseYear(dateStrings.date, additionalDigits) + date = parseDate(parseYearResult.restDateString, parseYearResult.year) + } + + if (isNaN(date) || !date) { + return new Date(NaN) + } + + var timestamp = date.getTime() + var time = 0 + var offset + + if (dateStrings.time) { + time = parseTime(dateStrings.time) + if (isNaN(time) || time === null) { + return new Date(NaN) + } + } + + if (dateStrings.timezone) { + offset = parseTimezone(dateStrings.timezone) + if (isNaN(offset)) { + return new Date(NaN) + } + } else { + var dirtyDate = new Date(timestamp + time) + // js parsed string assuming it's in UTC timezone + // but we need it to be parsed in our timezone + // so we use utc values to build date in our timezone. + // Year values from 0 to 99 map to the years 1900 to 1999 + // so set year explicitly with setFullYear. + var result = new Date(0) + result.setFullYear( + dirtyDate.getUTCFullYear(), + dirtyDate.getUTCMonth(), + dirtyDate.getUTCDate() + ) + result.setHours( + dirtyDate.getUTCHours(), + dirtyDate.getUTCMinutes(), + dirtyDate.getUTCSeconds(), + dirtyDate.getUTCMilliseconds() + ) + return result + } + + return new Date(timestamp + time + offset) +} + +function splitDateString(dateString) { + var dateStrings = {} + var array = dateString.split(patterns.dateTimeDelimiter) + var timeString + + // The regex match should only return at maximum two array elements. + // [date], [time], or [date, time]. + if (array.length > 2) { + return dateStrings + } + + if (/:/.test(array[0])) { + dateStrings.date = null + timeString = array[0] + } else { + dateStrings.date = array[0] + timeString = array[1] + if (patterns.timeZoneDelimiter.test(dateStrings.date)) { + dateStrings.date = dateString.split(patterns.timeZoneDelimiter)[0] + timeString = dateString.substr(dateStrings.date.length, dateString.length) + } + } + + if (timeString) { + var token = patterns.timezone.exec(timeString) + if (token) { + dateStrings.time = timeString.replace(token[1], '') + dateStrings.timezone = token[1] + } else { + dateStrings.time = timeString + } + } + + return dateStrings +} + +function parseYear(dateString, additionalDigits) { + var regex = new RegExp( + '^(?:(\\d{4}|[+-]\\d{' + + (4 + additionalDigits) + + '})|(\\d{2}|[+-]\\d{' + + (2 + additionalDigits) + + '})$)' + ) + + var captures = dateString.match(regex) + // Invalid ISO-formatted year + if (!captures) return { year: null } + + var year = captures[1] && parseInt(captures[1]) + var century = captures[2] && parseInt(captures[2]) + + return { + year: century == null ? year : century * 100, + restDateString: dateString.slice((captures[1] || captures[2]).length), + } +} + +function parseDate(dateString, year) { + // Invalid ISO-formatted year + if (year === null) return null + + var captures = dateString.match(dateRegex) + // Invalid ISO-formatted string + if (!captures) return null + + var isWeekDate = !!captures[4] + var dayOfYear = parseDateUnit(captures[1]) + var month = parseDateUnit(captures[2]) - 1 + var day = parseDateUnit(captures[3]) + var week = parseDateUnit(captures[4]) + var dayOfWeek = parseDateUnit(captures[5]) - 1 + + if (isWeekDate) { + if (!validateWeekDate(year, week, dayOfWeek)) { + return new Date(NaN) + } + return dayOfISOWeekYear(year, week, dayOfWeek) + } else { + var date = new Date(0) + if ( + !validateDate(year, month, day) || + !validateDayOfYearDate(year, dayOfYear) + ) { + return new Date(NaN) + } + date.setUTCFullYear(year, month, Math.max(dayOfYear, day)) + return date + } +} + +function parseDateUnit(value) { + return value ? parseInt(value) : 1 +} + +function parseTime(timeString) { + var captures = timeString.match(timeRegex) + if (!captures) return null // Invalid ISO-formatted time + + var hours = parseTimeUnit(captures[1]) + var minutes = parseTimeUnit(captures[2]) + var seconds = parseTimeUnit(captures[3]) + + if (!validateTime(hours, minutes, seconds)) { + return NaN + } + + return ( + hours * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + + seconds * 1000 + ) +} + +function parseTimeUnit(value) { + return (value && parseFloat(value.replace(',', '.'))) || 0 +} + +function parseTimezone(timezoneString) { + if (timezoneString === 'Z') return 0 + + var captures = timezoneString.match(timezoneRegex) + if (!captures) return 0 + + var sign = captures[1] === '+' ? -1 : 1 + var hours = parseInt(captures[2]) + var minutes = (captures[3] && parseInt(captures[3])) || 0 + + if (!validateTimezone(hours, minutes)) { + return NaN + } + + return ( + sign * (hours * MILLISECONDS_IN_HOUR + minutes * MILLISECONDS_IN_MINUTE) + ) +} + +function dayOfISOWeekYear(isoWeekYear, week, day) { + var date = new Date(0) + date.setUTCFullYear(isoWeekYear, 0, 4) + var fourthOfJanuaryDay = date.getUTCDay() || 7 + var diff = (week - 1) * 7 + day + 1 - fourthOfJanuaryDay + date.setUTCDate(date.getUTCDate() + diff) + return date +} + +// Validation functions + +// February is null to handle the leap year (using ||) +var daysInMonths = [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +function isLeapYearIndex(year) { + return year % 400 === 0 || (year % 4 === 0 && year % 100) +} + +function validateDate(year, month, date) { + return ( + month >= 0 && + month <= 11 && + date >= 1 && + date <= (daysInMonths[month] || (isLeapYearIndex(year) ? 29 : 28)) + ) +} + +function validateDayOfYearDate(year, dayOfYear) { + return dayOfYear >= 1 && dayOfYear <= (isLeapYearIndex(year) ? 366 : 365) +} + +function validateWeekDate(_year, week, day) { + return week >= 1 && week <= 53 && day >= 0 && day <= 6 +} + +function validateTime(hours, minutes, seconds) { + if (hours === 24) { + return minutes === 0 && seconds === 0 + } + + return ( + seconds >= 0 && + seconds < 60 && + minutes >= 0 && + minutes < 60 && + hours >= 0 && + hours < 25 + ) +} + +function validateTimezone(_hours, minutes) { + return minutes >= 0 && minutes <= 59 +} diff --git a/date-fns/src/parseISO/index.js.flow b/date-fns/src/parseISO/index.js.flow new file mode 100644 index 0000000..951a222 --- /dev/null +++ b/date-fns/src/parseISO/index.js.flow @@ -0,0 +1,57 @@ +// @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 = { + code?: string, + 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?: { + 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, + }, +} + +export type Duration = { + years?: number, + months?: number, + weeks?: number, + days?: number, + hours?: number, + minutes?: number, + seconds?: number, +} + +export type Day = 0 | 1 | 2 | 3 | 4 | 5 | 6 + +declare module.exports: ( + argument: string, + options?: { + additionalDigits?: 0 | 1 | 2, + } +) => Date diff --git a/date-fns/src/parseISO/test.js b/date-fns/src/parseISO/test.js new file mode 100644 index 0000000..36a8a90 --- /dev/null +++ b/date-fns/src/parseISO/test.js @@ -0,0 +1,452 @@ +// @flow +/* eslint-env mocha */ + +import assert from 'power-assert' +import parseISO from '.' + +describe('parseISO', () => { + describe('string argument', () => { + describe('centuries', () => { + it('parses YY', () => { + const result = parseISO('20') + assert.deepEqual(result, new Date(2000, 0 /* Jan */, 1)) + }) + }) + + describe('years', () => { + it('parses YYYY', () => { + const result = parseISO('2014') + assert.deepEqual(result, new Date(2014, 0 /* Jan */, 1)) + }) + }) + + describe('months', () => { + it('parses YYYY-MM', () => { + const result = parseISO('2014-02') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 1)) + }) + }) + + describe('weeks', () => { + it('parses YYYY-Www', () => { + const result = parseISO('2014-W02') + assert.deepEqual(result, new Date(2014, 0 /* Jan */, 6)) + }) + + it('parses YYYYWww', () => { + const result = parseISO('2014W02') + assert.deepEqual(result, new Date(2014, 0 /* Jan */, 6)) + }) + }) + + describe('calendar dates', () => { + it('parses YYYY-MM-DD', () => { + const result = parseISO('2014-02-11') + assert.deepEqual(result, new Date(2014, 1, /* Feb */ 11)) + }) + + it('parses YYYYMMDD', () => { + const result = parseISO('20140211') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11)) + }) + }) + + describe('week dates', () => { + it('parses YYYY-Www-D', () => { + const result = parseISO('2014-W02-7') + assert.deepEqual(result, new Date(2014, 0 /* Jan */, 12)) + }) + + it('parses YYYYWwwD', () => { + const result = parseISO('2014W027') + assert.deepEqual(result, new Date(2014, 0 /* Jan */, 12)) + }) + + it('correctly handles years in which 4 January is Sunday', () => { + const result = parseISO('2009-W01-1') + assert.deepEqual(result, new Date(2008, 11 /* Dec */, 29)) + }) + }) + + describe('ordinal dates', () => { + it('parses YYYY-DDD', () => { + const result = parseISO('2014-026') + assert.deepEqual(result, new Date(2014, 0 /* Jan */, 26)) + }) + + it('parses YYYYDDD', () => { + const result = parseISO('2014026') + assert.deepEqual(result, new Date(2014, 0 /* Jan */, 26)) + }) + }) + + describe('date and time combined', () => { + it('parses YYYY-MM-DDThh:mm', () => { + const result = parseISO('2014-02-11T11:30') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) + }) + + it('parses YYYY-MM-DDThhmm', () => { + const result = parseISO('2014-02-11T1130') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) + }) + }) + + describe('extended century representation', () => { + it('parses century 101 BC - 2 BC', () => { + const result = parseISO('-0001') + const date = new Date(0) + date.setFullYear(-100, 0 /* Jan */, 1) + date.setHours(0, 0, 0, 0) + assert.deepEqual(result, date) + }) + + it('parses century 1 BC - 99 AD', () => { + const result = parseISO('00') + const date = new Date(0) + date.setFullYear(0, 0 /* Jan */, 1) + date.setHours(0, 0, 0, 0) + assert.deepEqual(result, date) + }) + + it('parses centuries after 9999 AD', () => { + const result = parseISO('+0123') + assert.deepEqual(result, new Date(12300, 0 /* Jan */, 1)) + }) + + it('allows to specify the number of additional digits', () => { + const result = parseISO('-20', { additionalDigits: 0 }) + const date = new Date(0) + date.setFullYear(-2000, 0 /* Jan */, 1) + date.setHours(0, 0, 0, 0) + assert.deepEqual(result, date) + }) + }) + + describe('extended year representation', () => { + it('correctly parses years from 1 AD to 99 AD', () => { + const result = parseISO('0095-07-02') + const date = new Date(0) + date.setFullYear(95, 6 /* Jul */, 2) + date.setHours(0, 0, 0, 0) + assert.deepEqual(result, date) + }) + + it('parses years after 9999 AD', () => { + const result = parseISO('+012345-07-02') + assert.deepEqual(result, new Date(12345, 6 /* Jul */, 2)) + }) + + it('allows to specify the number of additional digits', () => { + const result = parseISO('+12340702', { additionalDigits: 0 }) + assert.deepEqual(result, new Date(1234, 6 /* Jul */, 2)) + }) + + it('parses year 1 BC', () => { + const result = parseISO('0000-07-02') + const date = new Date(0) + date.setFullYear(0, 6 /* Jul */, 2) + date.setHours(0, 0, 0, 0) + assert.deepEqual(result, date) + }) + + it('parses years less than 1 BC', () => { + const result = parseISO('-000001-07-02') + const date = new Date(0) + date.setFullYear(-1, 6 /* Jul */, 2) + date.setHours(0, 0, 0, 0) + assert.deepEqual(result, date) + }) + }) + + describe('float time', () => { + it('parses float hours', () => { + const result = parseISO('2014-02-11T11.5') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) + }) + + it('parses float minutes', () => { + const result = parseISO('2014-02-11T11:30.5') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30, 30)) + }) + + it('parses float seconds', () => { + const result = parseISO('2014-02-11T11:30:30.768') + assert.deepEqual( + result, + new Date(2014, 1 /* Feb */, 11, 11, 30, 30, 768) + ) + }) + + it('parses , as decimal mark', () => { + const result = parseISO('2014-02-11T11,5') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 11, 11, 30)) + }) + }) + + describe('timezones', () => { + describe('when the date and the time are specified', () => { + it('parses Z', () => { + const result = parseISO('2014-10-25T06:46:20Z') + assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) + }) + + it('parses ±hh:mm', () => { + const result = parseISO('2014-10-25T13:46:20+07:00') + assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) + }) + + it('parses ±hhmm', () => { + const result = parseISO('2014-10-25T03:46:20-0300') + assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) + }) + + it('parses ±hh', () => { + const result = parseISO('2014-10-25T13:46:20+07') + assert.deepEqual(result, new Date('2014-10-25T13:46:20+07:00')) + }) + }) + describe('when the year and the month are specified', () => { + it('sets timezone correctly on yyyy-MMZ format', () => { + const result = parseISO('2012-01Z') + assert.deepEqual(result, new Date('2012-01-01T00:00:00+00:00')) + }) + }) + }) + + describe('failure', () => { + it('returns `Invalid Date` if the string is not an ISO formatted date', () => { + const result = parseISO(new Date(2014, 8 /* Sep */, 1, 11).toString()) + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + }) + + describe('validation', () => { + describe('months', () => { + it('returns `Invalid Date` for invalid month', () => { + const result = parseISO('2014-00') + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + + describe('weeks', () => { + it('returns `Invalid Date` for invalid week', () => { + const result = parseISO('2014-W00') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` for 54th week', () => { + const result = parseISO('2014-W54') + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + + describe('calendar dates', () => { + it('returns `Invalid Date` for invalid day of the month', () => { + const result = parseISO('2012-02-30') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` for 29th of February of non-leap year', () => { + const result = parseISO('2014-02-29') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('parses 29th of February of leap year', () => { + const result = parseISO('2012-02-29') + assert.deepEqual(result, new Date(2012, 1, /* Feb */ 29)) + }) + }) + + describe('week dates', () => { + it('returns `Invalid Date` for invalid day of the week', () => { + const result = parseISO('2014-W02-0') + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + + describe('ordinal dates', () => { + it('returns `Invalid Date` for invalid day of the year', () => { + const result = parseISO('2012-000') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` for 366th day of non-leap year', () => { + const result = parseISO('2014-366') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('parses 366th day of leap year', () => { + const result = parseISO('2012-366') + assert.deepEqual(result, new Date(2012, 11, /* Dec */ 31)) + }) + }) + + describe('date', () => { + it('returns `Invalid Date` when it contains spaces after the date', () => { + const result = parseISO('2014-02-11 basketball') + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + + describe('time', () => { + it('parses 24:00 as midnight of the next day', () => { + const result = parseISO('2014-02-11T24:00') + assert.deepEqual(result, new Date(2014, 1 /* Feb */, 12, 0, 0)) + }) + + it('returns `Invalid Date` for anything after 24:00', () => { + const result = parseISO('2014-02-11T24:01') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` for invalid hours', () => { + const result = parseISO('2014-02-11T25') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` for invalid minutes', () => { + const result = parseISO('2014-02-11T21:60') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` for invalid seconds', () => { + const result = parseISO('2014-02-11T21:59:60') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` for invalid time', () => { + const result = parseISO('2014-02-11T21:basketball') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns `Invalid Date` when it contains spaces after the time', () => { + const result = parseISO('2014-02-11T21:59:00 basketball') + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + + describe('timezones', () => { + it('returns `Invalid Date` for invalid timezone minutes', () => { + const result = parseISO('2014-02-11T21:35:45+04:60') + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + }) + + describe('invalid argument', () => { + it('returns Invalid Date for date argument', () => { + // $ExpectedMistake + const date = new Date(2016, 0, 1) + const result = parseISO(date) + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date for timestamp argument', () => { + const timestamp = new Date(2016, 0, 1, 23, 30, 45, 123).getTime() + // $ExpectedMistake + const result = parseISO(timestamp) + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is non-date string', () => { + const result = parseISO('abc') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is non-date string containing a colon', () => { + const result = parseISO('00:00') + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is NaN', () => { + // $ExpectedMistake + const result = parseISO(NaN) + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is Invalid Date', () => { + // $ExpectedMistake + const result = parseISO(new Date(NaN)) + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is null', () => { + // $ExpectedMistake + const result = parseISO(null) + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is undefined', () => { + // $ExpectedMistake + const result = parseISO(undefined) + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is false', () => { + // $ExpectedMistake + const result = parseISO(false) + assert(result instanceof Date) + assert(isNaN(result)) + }) + + it('returns Invalid Date if argument is true', () => { + // $ExpectedMistake + const result = parseISO(true) + assert(result instanceof Date) + assert(isNaN(result)) + }) + }) + + describe('argument conversion', () => { + it('implicitly converts instance of String into a string', () => { + // eslint-disable-next-line no-new-wrappers + const dateString = new String('2014-02-11') + // $ExpectedMistake + const result = parseISO(dateString) + assert.deepEqual(result, new Date(2014, 1, /* Feb */ 11)) + }) + + it('implicitly converts options', () => { + // $ExpectedMistake + const result = parseISO('+12340702', { additionalDigits: '0' }) + assert.deepEqual(result, new Date(1234, 6 /* Jul */, 2)) + }) + + it('throws `RangeError` if `options.additionalDigits` is not convertable to 0, 1, 2 or undefined`', () => { + // $ExpectedMistake + const block = parseISO.bind(null, '+12340702', { additionalDigits: 3 }) + assert.throws(block, RangeError) + }) + }) + + it('throws TypeError exception if passed less than 1 argument', () => { + assert.throws(parseISO.bind(null), TypeError) + }) +}) |