feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: add new isDate() validator - #1270

Merged
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate
Apr 6, 2020
Merged

feat: add new isDate() validator#1270
profnandaa merged 7 commits into
validatorjs:masterfrom
mum-never-proud:add-support-for-isDate

Conversation

@mum-never-proud

@mum-never-proudmum-never-proud commented Mar 22, 2020

Copy link
Copy Markdown
Contributor

Resolves#1130

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and welcome to the project! 🎉 See my comments below.

Comment threades/lib/isEmail.js Outdated
@@ -1,8 +1,12 @@
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove this file from the diff since it's unrelated to the PR.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was auto-generated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just remove it before committing. This is because of the difference in the build system.

Comment threadtest/validators.js
'2015-07-15T07:00:00+0000',
],
invalid: [
'',

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try add the following test cases:

2020-02-30, // invalid date
2019-02-29, // non-leap year
2020-04-31, // invalid date

I presume all those will pass as true (or fail as false). We will need to handle these cases.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since:

> new Date('2020-02-31')
2020-03-02T00:00:00.000Z
> new Date('2020-04-31')
2020-05-01T00:00:00.000Z

@mum-never-proudmum-never-proudMar 22, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice catch!

a simple validation would be

>newDate('2020-02-30').getUTCDate()1>newDate('2019-02-29').getUTCDate()1>newDate('2020-02-29').getUTCDate()29

we can compare it with the date supplied

the problem here is with the date format some may give as YYYY-MM-DD or MM-DD-YYYY

we can do that! my bad

any suggestion?

any better way ?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd not thought of that way, I think I like it! 👍

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm looks like there are many edge cases to be considered in this case,

what if a user supplies

MM-DD-YYYY
YYYY-MM-DD
YY-MM-DD
MM-DD-YY

we need to keep things simple and general

any suggestion?

@profnandaaprofnandaaMar 22, 2020

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, for now let's just support those that are supported by Date(), and strictly YYYY. Need to add that note on the README.

However, I noticed something else, look at this?

> new Date('02-02-2019')
2019-02-01T21:00:00.000Z // .getUTCDate() = 1
> new Date('2019-02-02')
2019-02-02T00:00:00.000Z // .getUTCDate() = 2

Perhaps this are some of the intricacies that led to deprecating the first isDate() from the library. 🤔

What if we allowed the user to supply the format from a list of predefined formats?

MM-DD-YYYY
DD-MM-YYYY
YYYY-MM-DD

Then transform this to a YYYY-MM-DD format before running it through new Date()

@mum-never-proudmum-never-proudMar 23, 2020

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out the fiddle

https://jsfiddle.net/hvrwp07e/1/

I have done some tweaking, I have some stuff to do so right now I don't have time to think about edge cases

feel free to introduce some edge case or enhance the code

let me know if you are aware of any edge cases

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking forward to that we can do more addition on edge cases in the future and update the readme accordingly.

@profnandaaprofnandaa changed the title add support for is datefeat: add new isDate() validatorMar 22, 2020
@profnandaa

Copy link
Copy Markdown
Member

/cc. @tux-tn@ezkemboi -- your thoughts?

@profnandaaprofnandaa mentioned this pull request Mar 22, 2020
@ezkemboi

Copy link
Copy Markdown
Member

I will check on this @profnandaa.

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

I have made the necessary changes to support almost all the format and handling leap years, invalid dates, etc

I have added a few more test cases, let me know if we need more test cases

have a look and let me know for any further changes!

cc: @profnandaa

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

Comment threadsrc/lib/isDate.js
return new Date(`${dateObj.m}/${dateObj.d}/${dateObj.y}`).getDate() === +dateObj.d;
}

return Object.prototype.toString.call(input) === '[object Date]' && isFinite(input);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this last call for? The assumption is that input will always be a string. You need to call assertString() at the top of the function...

Comment threadsrc/lib/isDate.js
@@ -0,0 +1,35 @@
function isValidFormat(format) {
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd thought we'll come up with multiple regex depending with the format provided, starting with YYYY/MM/DD as a default.

We said we'll keep it simple as just date string only, nothing else.

@mum-never-proud

mum-never-proud commented Mar 26, 2020

Copy link
Copy Markdown
ContributorAuthor

Suggesting a rework to simplify, let me know if it makes sense.

Thanks for the efforts so far.

agreed that the regex part might seem complicated but its quite simple, I guess it's better to support all format with a little effort

let me break down this code into simple chunks

isDate supported argument types

object: check if the object type is Date
string: if string proceed with below steps

functionisValidFormat(format){return/(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);}

this part checks for the following patterns

  • YYYY-MM-DD

  • YY-MM-DD

  • YYYY-M-D

  • YY-M-D

  • MM-DD-YYYY

  • MM-DD-YY

  • M-D-YYYY

  • M-D-YY

  • DD-MM-YYYY

  • DD-MM-YY

  • D-M-YYYY

  • D-M-YY

functionzip(x,y){constzippedArr=[],len=Math.min(x.length,y.length);leti=0;for(;i<len;i++){zippedArr.push([x[i],y[i]]);}returnzippedArr;}

the above one just zips two arrays into one, for example, consider the input as 07/15/2002 and format as MM/DD/YYYY

splitting the above inputs [\/-] will yield two arrays

zipping them will yield this

['MM', '07']
['DD', '15']
['YYYY', '2002']

after zipping the arrays in this part

for(const[dateWord,formatWord]ofdateAndFormat){if(dateWord.length!==formatWord.length){returnfalse;}dateObj[formatWord.charAt(0)]=dateWord;}

we just check for length equality for eg. 'MM'.length === '07'.length if not we return false else we store in an object with first character of format

obj[d] = 15, obj[m] = 7, obj[y] = 2002

then we init the date and check for validity by getting the date and the original input if both dates are same it is a valid date else nope

let me know if anything is unclear, I hope this should work for almost all of the cases you can also refer the test cases

cc: @profnandaa

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ok, sounds good. Thanks!

@profnandaaprofnandaa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

More review from @tux-tn and @ezkemboi then we land. Thanks for your contrib! 🎉

@profnandaaprofnandaa mentioned this pull request Mar 31, 2020
@profnandaa

Copy link
Copy Markdown
Member

@ezkemboi -- ping

@ezkemboi

Copy link
Copy Markdown
Member

Doing the review @profnandaa. I was held up by some work here.

Comment threadtest/validators.js
validator: 'isDate',
valid: [
new Date(),
new Date([2014, 2, 15]),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means we allow users to send created dates using the new Date() method?
I thought, we just need to pass a string. But, it is a good idea.

Comment threadsrc/lib/isDate.js Outdated
return /(^(y{4}|y{2})[\/-](m{1,2})[\/-](d{1,2})$)|(^(m{1,2})[\/-](d{1,2})[\/-]((y{4}|y{2})$))|(^(d{1,2})[\/-](m{1,2})[\/-]((y{4}|y{2})$))/gi.test(format);
}

function zip(x, y) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would prefer if we make use of something like

functionzip(date,format){}

Use of x, y a little bit makes the code harder to read.

Comment threadsrc/lib/isDate.js Outdated
len = Math.min(x.length, y.length);
let i = 0;

for (; i < len; i++) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for(leti=0;i<len;i++){}

Might seem better than let i = 0 and use ; to make separation.

@profnandaa

Copy link
Copy Markdown
Member

@mum-never-proud -- ^

@mum-never-proud

Copy link
Copy Markdown
ContributorAuthor

@profnandaa sorry was busy, I will update the changes in few hours!

@profnandaa
profnandaa merged commit ff11844 into validatorjs:masterApr 6, 2020
@profnandaaprofnandaa mentioned this pull request May 19, 2020
@pavan-shipmnts

Copy link
Copy Markdown

When is this releasing?

@profnandaa

Copy link
Copy Markdown
Member

Most likey by end of May or 1st half of June.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isDate()

4 participants

@mum-never-proud@profnandaa@ezkemboi@pavan-shipmnts