Date validation for months in javascript - javascript

I was referring this link and as I do not have 50 reputation I am not allowed to comment in the answer so posting this question. I did not get the statement where you can see a month is subtracted from months. This can be simple one but could anyone please clarify on this?
var m = matches1 - 1; ?
function isValidDate(date)
{
var matches = /^(\d{2})[-\/](\d{2})[-\/](\d{4})$/.exec(date);
if (matches == null) return false;
var d = matches[2];
var m = matches[1] - 1;
var y = matches[3];
var composedDate = new Date(y, m, d);
return composedDate.getDate() == d &&
composedDate.getMonth() == m &&
composedDate.getFullYear() == y;
}

var m = matches1 - 1; ?
months index starts from 0.
So while you think Jan is 1, it is actually 0 when you do date.getMonth().
Which is why when you get 1 from a date-string, you need to make it 0 before setting it to a date object.

In the spirt of the question, the validation function is way overdone. Only the month needs to be checked since if either the day or month is out of bounds, the month of the generated date will change.
Also the regular expression can be greatly simplified, consider (assuming the input is the peculiar US m/d/y format):
/* Validate a date string in US m/d/y format
** #param {string} s - string to parse
** separator can be any non–digit character (.-/ are common)
** leading zeros on values are optional
** #returns {boolean} true if string is a valid date, false otherwise
*/
function validateMDY(s) {
var b = s.split(/\D/);
var d = new Date(b[2],--b[0],b[1]);
return b[0] == d.getMonth();
}
var testData = ['2/29/2016', // Valid - leap year
'2/29/2015', // Invalid - day out of range
'13/4/2016', // Invalid - month out of range
'13/40/2016', // Invalid - month and day out of range
'02/02/2017']; // Valid
document.write(testData.map(function(a) {
return a + ': ' + validateMDY(a);
}).join('<br>'));

Related

Check if Date is in Range

I have a date range suppose 2000-01-01 to 2021-06-01. I want to check whether a particular month with a given year falls in this range or not (E.g., month = March and year = 2021) using JavaScript.
Create a reusable function isDateInRange that accepts your three date Strings arguments.
Than you can simply compare your Date Objects using the needed operands:
const isDateInRange = (date, from, to) => {
const d = new Date(date);
const f = new Date(from);
const t = new Date(to);
return (d >= f && d < t);
};
console.log(isDateInRange("2001-01-31", "2000-01-01", "2021-06-01")) // true
console.log(isDateInRange("2050-01-01", "2000-01-01", "2021-06-01")) // false
Here is a solution passing month and year (not a date) as you requested.
const lowerRange = new Date('2000-01-01');
const upperRange = new Date('2021-06-01');
// If month and year are numbers
const monthYearInRange = (year, month) => {
if (typeof month !== 'number') throw new Error('Month should be number');
if (typeof year !== 'number') throw new Error('Year should be number');
// We do this to make sure it is 2 chars.
const mth = month < 10 ? `0${month}` : month;
// Set it to first of the month
const checkVal = new Date(`${year}-${mth}-01`);
if (isNaN(checkVal)) throw new Error(`Year: ${year} and Month: ${month} are not valid.`);
return checkVal <= upperRange && checkVal >= lowerRange;
}
console.log(monthYearInRange(2000, 2)); // true
console.log(monthYearInRange(2030, 2)); // false
console.log(monthYearInRange(2021, 6)); // true
console.log(monthYearInRange(2021, 10)); // false
Just a note on this solution - because ultimately we convert the year/month into a date, when doing this we have to instantiate the date using the ISO format YYYY-MM-DD. If checkVal gets instantiated with a month that is a single character (1 instead of 01) it will still work in most cases - but you will get edge cases breaking because the Date() constructor will add timezone values to the date.
Update: Added NaN check - per #RobG
I tried the following approach and it worked:
function isBetween(n, a, b) {
return (n - a) * (n - b) <= 0
}
var startDate = '2021-03-15';
var endDate = '2021-06-01';
var checkFor = '2021-05-31';
D_1 = startDate.split("-");
D_2 = endDate.split("-");
D_3 = checkFor.split("-");
//console.log(D_1+" "+D_2+" "+D_3);
var startNumber = D_1[0]*100 + D_1[1];
var endNumber = D_2[0]*100 + D_2[1];
var checkNumber = D_3[0]*100 + D_3[1];
var check = isBetween(checkNumber, startNumber, endNumber);
console.log(check);

datetime not returning correct value

Using only JS Write a function that converts user entered date formatted as M/D/YYYY to a format required by an API (YYYYMMDD). The parameter "userDate" and the return value are strings.
For example, it should convert user entered date "12/31/2014" to "20141231" suitable for the API.
I have wrote:
function formatDate(userDate) {
// format from M/D/YYYY to YYYYMMDD
var myDate = new Date(userDate);
var day = myDate.getDay();
var month = myDate.getMonth();
var year = myDate.getFullYear();
var d = day.toString();
var m = month.toString();
var y = year.toString();
return y + m + d;
}
console.log(formatDate("12/31/2014"));
but this is returning: 2014113
should it not return '20141231'
Thanks to #gurvinder372 by +1 I was able to get '20141231'
but the answer is telling me iv passed 0 out of 4...Ive failed on:
Example case: Wrong answer
Two-digit month and day: Wrong answer
One-digit day: Wrong answer
One-digit month: Wrong answer
Months in Date are counted from 0, so this:
myDate.getMonth();
will return 0 for January and so on.
Moreover this:
var day = myDate.getDay();
represents, the day of the week counted from 0, so it should be replaced with this:
var day = myDate.getDate();
For one-digit values, you need to check if it's less than 10 and conditionally prepend it with 0. So the final form of this should be:
function formatDate(userDate) {
// format from M/D/YYYY to YYYYMMDD
var myDate = new Date(userDate);
var day = myDate.getDate();
var month = myDate.getMonth() + 1;
var year = myDate.getFullYear();
var d = +day.toString() < 10 ? '0' + day.toString() : day.toString();
var m = +month.toString() < 10 ? '0' + month.toString() : month.toString();
var y = year.toString(); // no need for check one-digit values
return y + m + d;
}
Hope this helps you
function formatDate(userDate) {
var myDate = new Date(userDate);
var day = myDate.getDate();
var month = myDate.getMonth() + 1; // +1 as month starts with o
var year = myDate.getFullYear();
var d = (day <= 9) ? '0' + day : day.toString(); // append 0 for single digit
var m = (month <= 9) ? '0' + month : month.toString(); // append 0 for single digit
var y = year.toString();
return y + m + d;
}
console.log(formatDate("1/1/2014"));
You can even get rid of using Date constructor. Parsing with date constructor is usually not recommended unless you are using ISO-8601 format as implementation differs in browsers for other formats.
Here is an example with just string split() function.
If you want zero padding for single digit numbers, make use of the pad() function which formats 1 as 01.
function formatDate(userDate) {
// format from M/D/YYYY to YYYYMMDD
var dateArray = userDate.split('/');
var m = +dateArray[0];
var d = +dateArray[1];
var y = +dateArray[2];
var pad = function(n){return n >= 10? n : '0'+n};
// if you want zero padding
// return '' + pad(y) + pad(m) + pad(d);
return '' + y + m + d;
}
console.log(formatDate("12/31/2014"));
but this is returning: 2014113 should it not return '20141231'
Month starts from 0
Replace
var month = myDate.getMonth();
with
var month = myDate.getMonth() + 1;
If you also need to take care of single-digit padding, then do this as well
function padToTwoChar( value )
{
return ( "0" + value ).slice(-2);
}
and your return statement will become
return padToTwoChar( y ) + padToTwoChar( m ) + padToTwoChar( d );

Parsing strings for Math operations in Javascript

I have two values. one a [STRING] and one an [INT]
TimeZone is a string of one of these values:
'EST-5:00' || 'CST-6:00' || 'MST-7:00' || 'PST-8:00'
DST will be an INT of 0 || 1.
Trying to figure out how best to get offset.
offset = MATH.abs(TimeZone# + DST) ie.
let offset = MATH.abs(-5 + 1) // = 4 ('EST-5:00') + (DST = 1)
or
let offset = MATH.abs(-6 + 0) // = 6 ('CST-6:00') + (DST = 0)
or
let offset = MATH.abs(-8 + 1) // = 7 ('PST-8:00') + (DST = 1)
What is the best way to parse the string to get the number value and add the value of DST?
My end goal is actually to get a DateTime I have such as:
let DateTime = '2017-05-11 10:34:43'
along with the TimeZone String above (retrieved from metadata related to the event) and transform it to UTC using the DST Int (retrieved from metadata related to the event) ...
So I am trying to find out how much I need to add (hours) to the DateTime to set it to UTC given the data I have to work with.
so
let utcTime = moment(DateTime).add(offset, 'h');
You could do a regular expression with a match group on the digit:
var value = '(\'PST-8:00\')'.match(/\w{3}-(\d{1})\:/).pop() + DST // => 8 + DST
It looks for a series of 3 word characters, followed by a hyphen, and then matches on a single digit, before ending at a colon character.
This was just a quick on off the top of my head, so I'm sure there are ways to tighten up the regex, but the principle is still the same (see the String.prototype.match docs on MDN).
You only want the number part, so you can use a regular expression to get the hour and minute values:
var tz = 'EST-5:00';
var hm = tz.match(/[+-]?\d\d?/g);
will get the time parts. hm[0] is the hour part with sign and `hm[1] is the minute part. If you want the letter part as well, that can be accommodated too:
var hm = tz.match(/[a-z]+|[+-]?\d\d?/ig);
Some timezones go down to 15 minutes and daylight offsets can be 30 minutes, so it's more compatible to express the offset in minutes than hours (though it should be in ±hh:mm format for humans). You should also keep the minutes part and the sign:
var tz = 'EST-5:00';
function offsetToMins(s) {
var hm = s.match(/[+-]?\d\d?/g) || []; // Avoid null
var h = hm[0] * 60;
var m = +hm[1];
// A bit of validation
if (isNaN(h) || isNaN(m)) {
return 'Invalid input: ' + '"' + s + '"';
}
return h + (h<0? m*-1 : m);
}
console.log(offsetToMins(tz)) // -300
console.log(offsetToMins('IST+05:30')) // 330
console.log(offsetToMins('foo')) // Invalid input: "foo"
Now the daylight saving offset can be added in minutes and the value can be presented in a suitable human readable format, e.g. -06:00, -6:00, -0600, whatever.

Javascript - greater than/less than using 4 digits, that can start with 0?

This may sound like a dumb question, but is it possible to have a 0 at the start of a number check, and have it work?
This is what I have:
function checkCosts() {
var date = document.getElementsByName("date")[0].value;
var roomtype = document.getElementsByName("roomtype")[0].value;
var night = document.getElementsByName("night")[0].value;
var month = date.substring(0, 2);
var year = date.substring(8, 10);
var day = date.substring(4, 6);
var time = month.concat(year);
var fulldate = day.concat(time);
if (time >= 0415 && <= 0915) {
if (roomtype == "Classic") {
if (night == "3") {
document.getElementById("cost").innerHTML = "1,480";
}
}
}
}
However, when I run it in jslint.com I get the following errors:
Unexpected '4' after '0'.
if(time >= 0415 && <= 0915){
line 9 column 28Unexpected trailing space.
if(time >= 0415 && <= 0915){
What's there is just one of a few different statements, all the variables will be used.
It would be possible to convert the strings into ints, but I don't know how to do this/if it will work.
A leading 0 is not the way to use ints. You should take a look here.
Otherwise just use the alpabetical order using a string comparison.
There is just no need to add zeros in front of the number. If the first number identifies the level of the room just add it, where you need it.
Instead of concatenating month with year, Concatenate year with month, And then check.
You need to do some modification in your logic.
function checkCosts() {
var date = document.getElementsByName("date")[0].value;
var roomtype = document.getElementsByName("roomtype")[0].value;
var night = document.getElementsByName("night")[0].value;
var month = date.substring(0, 2);
var year = date.substring(8, 10);
var day = date.substring(4, 6);
var time = year.concat(month);//Concat year with month.
var fulldate = day.concat(time);
if (time >= 1504 && <= 1509) { //Year should be first
if (roomtype == "Classic") {
if (night == "3") {
document.getElementById("cost").innerHTML = "1,480";
}
}
}
}
If you are trying to convert date to number and want to compare, use year first then month.
from this:
var time = month.concat(year);
I deduce "time" is a string.
then you should put quotes on 0415
strings are compared using alphabetical order (I hope you don't need globalization in this comparison) :
"04".concat("16") >= "0415"
-> true
"04".concat("14") >= "0415"
-> false

Need help extracting date, month, and year from this date format

I need help converting this date format.
Here are the date string I receive from a server, it can be M/DD/YYYY or M/D/YYYY or MM/D/YYYY or MM/DD/YYYY.
EDIT: Sorry, my bad. After the format above, there is additional string of time HH:MM:SS AM so the complete string I receive will be M/D/YYYY HH:MM:SS AM
My problem now is I use String.substring(x, y) to extract the date, month, and year.
So far I only managed to determine the location of "/" but I'm still thinking how to use it in the substring method.
var separators = [];
for(var b = 0, c = String.length; b < c; b++){
if(String[b] === '/'){
separators.push(b);
}
}
I'm confused how to extract the date and month dynamically and then pad "0" in front of the single digit number, so I appreciate any helps. Thank you in advance.
var dt = "10/6/2012 12:34:56 AM".split(' ');
dt = dt[0].split('/');
// dt[0] => month
// dt[1] => day
// dt[2] => year
it works with any of the above format - M/DD/YYYY or M/D/YYYY or MM/D/YYYY or MM/DD/YYYY - (and it's easier than using substring)
then to add a pad to month and day just use slice() like so
dt[0] = ("0"+ dt[0]).slice(-2);
dt[1] = ("0"+ dt[1]).slice(-2);
and to get a padded data just re-join the array parts
dt = dt.join('/');
Example jsbin : http://jsbin.com/exodos/2/edit
var date= '1/3/2012'//your date string
,dateArray = date.split("/");
for(var k =0; k < 2; k++){
if((dateArray[k] + "").length ==1){
dateArray[k] = "0"+dateArray[k];
}
}
var newDate= dateArray.join("/");
jsfiddle
A regular expression can do the job. The following doesn't care whether it's a date as m/d/y or y/d/m/ or whatever, it just pads single digit numbers with a leading zero. It only works with integers, it will not behave well with decimal seconds.
function fixDate(d) {
var re = /\d+/g;
return d.replace(re, function(s) {
return (s < 10? '0' : '') + +s;
});
}
fixDate('2/3/2012 3:5:3 am'); // 02/03/2012 03:05:03 am

Categories