I am working on a system at the moment, that has rules based around dates ranges,
a user can submit a form, I need to check to date inputs fit within 1 of 3 dates ranges. Basically the 2 dates need to be within 1 of the 3 following rules,
01/01 - 30/04
01/05 - 30/09
01/10 - 31/12,
I need to workout what month the start date has and what month the end date has basically, and if the end date is outside of the it's range log it.
So basically, if a user submitted 01/01/2017 as a start date and 10/02/2017 as an end date, that would be a valid input, but if a user entered 01/01/2017 as a start date, and 01/06/2017 as end date that would be invalid as the date spans more than one date range.
Is it possible to check this kind of thing with javascript? I have gone through various scenarios, but the ranges in arrays and checking against array values, but I keep getting myself in a mess.
You can simply check if a date is in range with getTime()
JSBin
const isDateInRage = (startDate, endDate) => (dateToCheck) => {
return dateToCheck >= startDate && dateToCheck <= endDate
}
const isInRangeOne = isDateInRage('2016-01-01', '2016-04-30')
console.log('inRange', isInRangeOne('2016-01-02'))
console.log('outtOfRange', isInRangeOne('2016-07-02'))
Try this
// parse string 'XX/XX/XXXX' to create date object
function parseDate(str) {
var mdy = str.split('/');
return new Date(mdy[2], mdy[0]-1, mdy[1]);
}
function daysBetween(date1, date2) {
return Math.round((parseDate(date1)-parseDate(date2)) / (1000*60*60*24));
}
if(daysBetween('01/01/2017', '01/06/2017') > 1) {
// Your code here
}
Consider a function to test the start and end dates for each of the ranges and return true as soon as it fits in one of them. You'll need to correctly parse the strings, and also use the year from either the start or end date and apply it to the ranges.
The function below uses the start date and returns true if the start and end fit in one of the ranges, and false otherwise. If either the supplied start or end dates are invalid, it throws an error.
// Parse date in yyyy-mm-dd format as local date
function parseYMD(s) {
var b = s.split(/\D/);
var d = new Date(b[0], --b[1], b[2]);
return d && d.getMonth() == b[1]? d : new Date(NaN);
}
// Check start and end date are within one of the valid ranges
var checkInRange = (function () {
// Bespoke parser
function parsePart(p, y) {
p = p.split(/\D/);
return new Date(y, p[1]-1, p[0]);
}
// Valid ranges as d/m, year is taken from start date
var validRanges = ['01/01 - 30/04','01/05 - 30/09','01/10 - 31/12'];
return function (startDate, endDate) {
var dStart = parseYMD(startDate);
var dEnd = parseYMD(endDate);
// Throw error if input dates aren't valid
if (isNaN(dStart) || isNaN(dEnd)) {
throw new Error('start or end date is invalid')
}
var year = dStart.getFullYear();
// Return true if range is within valid ranges
return validRanges.some(function(range) {
var r = range.split(' - ').map(function(s){return parsePart(s, year)});
return dStart >= r[0] && dEnd <= r[1];
});
}
})();
// Some tests
[['2016-01-01','2016-04-30'],['2016-03-30','2016-04-30'],['2017-04-30','2017-05-01']].
forEach(function(dates) {
console.log('Start and end: ' + dates[0] + ' - ' + dates[1] +
'\nValid range?: ' + checkInRange(dates[0],dates[1]));
});
Do not use the Date constructor (or Date.parse) to parse strings. Their behaviour is largely implementation dependent. An ISO 8601 format date will be parsed as UTC, which is OK in this context as long as all of the strings are parsed identically, however if they aren't, users will
Related
We currently accept HL7 data through mirth and one of the field we process is date of birth, which we receive in PID.7.1 segment of HL7. Currently we just capture it like -
var vDOB = formatDate(msg['PID.7.1'].toString(),"yyyyMMdd");
How can I validate day , month and year component in the date. And also like it should be greater than today's date.
Thanks
You can include a function like this:
var dateChecker = function(dateStr){
if(date.length !=8 && !date.match('[0-9]{8}')) return false;//should be number and length 8
var year = date.substr(0,4);
var month = date.substr(4,2);
var day = date.substr(6,2);
var dateObj = new Date(year,month,day);
if (dateObj == 'Invalid Date') return false;
if(dateObj.getTime() - Date.now() > 0) return false;//compare epoch to check if date is less than current date/time
return true;
}
and then dateChecker(vDOB) should return true/false depending on whether the date is valid or invalid.
I'm trying to check the users input field to see if it is in the future and if it is in dd/mm/yyyy format but I have no idea why the format part of my code doesn't fire at all! In fact nothing seems to be working on Jsfiddle but at least my "check date in the future" function works locally.
I don't know the correct way of going about this.
to explain this, I've created this FIDDLE
And this is my full javascript code. I need to stay with pure javascript by the way:
function checkdate(){
//var sendDate = document.getElementById('send_year').value + '/' + document.getElementById('send_month').value + '/' + document.getElementById('send_day').value;
var sendDate = document.getElementById('returning_date').value;
sendDate = new Date(Date.parse(sendDate.replace(/-/g,' ')))
today = new Date();
today.setHours(0,0,0,0)
if (sendDate < today) {
//alert('The date can\'t be in the past. Please pick another date.');
document.getElementById('error8').innerHTML = 'The date can\'t be in the past. Please pick another date.';
return false;
}
else
{
document.getElementById('error8').innerHTML = '';
}
if(sendDate.match(/^[0-9]{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])/))
{
alert('works out');
}
}
could someone please advise on this issue?
Thanks in advance.
One problem is that you are trying to run sendDate.match, but sendDate has been converted into a Date object so it does not have a match method.
You should run your regular expression before you convert it to a Date, in validation, you typically check that the input conforms to a format before you run further validation like range validation.
Date strings should always be manually parsed, you should never allow the Date constructor or Date.parse to parse strings (the Date constructor parses strings in exactly the same way Date.parse does).
To parse and validate a date string is fairly straight forward, just parse the string and see if you get a valid date:
/* Parse a string in d/m/y format. Separator can be any non–digit
** Avoid conversion of two digit dates to 20th century
** Returns an invalid Date if string is not a valid date (per ECMA-262)
**
** #param {string} s - Date string to parse
** #returns {Date}
*/
function parseDMY(s) {
var b = s.split(/\D/);
var d = new Date();
d.setHours(0,0,0,0);
d.setFullYear(b[2], --b[1], b[0]);
return d && d.getMonth() == b[1]? d : new Date(NaN);
}
// Test valid date
document.write(parseDMY('23/01/2016'));
// Test invalid date
document.write('<br>' + parseDMY('35/12/2016'));
Note that this will accept a date like 1/5/16 and treat is as 1 May, 0016. If you want to guarantee that the day and month values have two digits and the year for, then add:
/^\d\d\D\d\d\D\d{4}$/.test(s)
to the validation test at the end. However, I don't like forcing 2 digits for day and month as people don't usually write dates as "01/08/2016", they use "1/8/2016".
First of all, the function needs to be wrapped in <head> (hit the cog in the js tab), otherwise the function can't be found.
But your main problem is that you are using European style of date formatting, so you'll get a "Invalid Date" exception when creating the date. Refer to this question on how to convert it to USA-style and make it available for the Date object (check the reference for all possible uses)
My proposal is:
Date.prototype.fromString = function(str) {
var m = str.match(/([0-9]{2})(-|\/)([0-9]{2})(-|\/)([0-9]{4})/);
if (m == null) {
return null;
}
for (var i = 0; i < m.length; i++) {
if (typeof(m[i]) === 'undefined') {
return null;
};
};
var year = parseInt(m[5]);
var month = parseInt(m[1]) - 1;
var day = parseInt(m[3]);
if (month == 0 || day == 0) {
return null;
}
return new Date(year, month, day);
}
function checkdate(e, obj, errMsgSel){
var sendDate =obj.value;
sendDate = (new Date()).fromString(sendDate);
if (sendDate == null) {
if (e.type == 'blur') {
obj.value = '';
}
return;
}
today = new Date();
today.setHours(0,0,0,0)
if (sendDate < today) {
//alert('The date can\'t be in the past. Please pick another date.');
document.getElementById(errMsgSel).innerHTML = 'The date can\'t be in the past. Please pick another date.';
return false;
}
else
{
document.getElementById(errMsgSel).innerHTML = '';
}
} $(function () {
});
<input onblur="checkdate(event, this, 'error8');" onKeyUp="checkdate(event, this, 'error8');" type='text' name="text1" placeholder='dd/mm/yyyy' id='returning_date'>
<span id='error8' style='color:red;'>format</span> <br><Br>
I have got below java script code that will validates date range ... when the user entered the today date or any future dates I have set IsValid to true and then will do the save operation ....
for that purpose I have written below code ..
function Save(e) {
var popupNotification = $("#popupNotification").data("kendoNotification");
var container = e.container;
var model = e.model;
var isValid = true;
var compareDate = e.model.DeliveryDate;
alert(compareDate);
var todayDate = new Date();
var compareDateModified = new Date(compareDate)
alert(compareDateModified);
if (compareDateModified > todayDate || compareDateModified === todayDate) {
isValid = true;
}
else
isValid = false;
e.preventDefault();
if (isValid == false)
{
popupNotification.show("Delivery Date should be today date or Greater", "error");
}
$('#Previous').show();
$('#Next').show();
}
Its working fine when I give the future dates but its not working for today date. I also need to check the today's date. I am not able to figure it out the error alert when I try to enter to the today date .
You are comparing two objects of the same type, but different objects, so that will always result in 'unequal'
If you use date.getTime() you will get better results in your comparison - but only if the time component is the same of course.
Think of the Date object like a timestamp. It is based on the unix-style of timestamps (the amount of seconds since 1st January, 1970) so the Date object isn't the day, it is the Date AND the Time.
What you're comparing is the times as well, which could get a little iffy. If only days matter, try using:
fullCompareDate = compareDateModified.getFullYear() + "/" + compareDateModified.getMonth() + "/" + compareDateModified.getDate();
fullTodayDate= todayDate.getFullYear() + "/" + todayDate.getMonth() + "/" + todayDate.getDate();
if(compareDateModified>todayDate||fullCompareDate==fullTodayDate)
{
//Do something
}
This will compare the date and time to make sure they are greater OR check the current date with the compare date (as strings)
Another solution is to blank out the times on both dates:
compareDateModified.setHours(0,0,0,0);
todayDate.setHours(0,0,0,0);
if(compareDateModified>=todayDate)
{
//Do something
}
You are comparing the compareDateModified to todayDate on the millisecond level. To compare at the day level:
var todayDate = new Date();
todayDate.setHours(0,0,0,0);
//you may also have to truncate the compareDateModified to the first
//second of the day depending on how you setup compareDate
if (compareDateModified >= todayDate) {
isValid = true;
}
I use Date() function to convert string to date object . The problem is , If i give Date("April , 31 ,2012") it will take it as May , 01 , 2012 (for the rest of the days its working) Please check my approach is correct from the code below.
function TestDate(objValue,strError){
var ret=true;
var frmdate=objValue.value;
var datesplit=frmdate.split("-");
var y =datesplit[0];
var m=datesplit[1];
var d=datesplit[2];
var testdate;
// Create date object using given input data
testdate = new Date(m+"/"+d+"/"+y);
alert("Created date"+testdate.toString());
var td=testdate.getDate();
var tm=testdate.getMonth()+1;
var ty =testdate.getFullYear();
alert(d+"="+td);
alert(m+"="+tm);
alert(y+"="+ty);
var valid=((d==td) && (m==tm) && (y==ty));
alert(valid);
if(valid == false)
{
ret =false;
}
return ret;
}
As sayed by #ajreal in comments, April has only 30 days.
The internal date object increments the month to have a valid date.
The code:
testdate = new Date(m+"/"+d+"/"+y);
is depends on non-standard, implementation specific parsing of the string. Far better to use the data you started with to create a date unambiguously:
testdate = new Date(y, m - 1, d);
As for validating a date, a simple function using an ISO8601 compliant date of format yyyy-mm-dd is:
function validateDate(dateString) {
var bits = dateString.split('-');
var date = new Date(bits[0], bits[1] - 1, bits[2]);
return date && date.getFullYear() == bits[0] && date.getDate() == bits[2];
}
That way if the string passed to the function is turned into a date, you can check that the date so created matches the input. If not, it wasn't valid and the function returns false. It also returns false if the string doesn't get turned into a date.
What could be the cause of the validateDate() function not to execute when called?
The purpose of validateDate() is to take a string like 01/01/2001 and call isValidDate() to determine if the date is valid.
If it's not valid, then a warning message will appear.
function isValidDate(month, day, year){
/*
Purpose: return true if the date is valid, false otherwise
Arguments: day integer representing day of month
month integer representing month of year
year integer representing year
Variables: dteDate - date object
*/
var dteDate;
//set up a Date object based on the day, month and year arguments
//javascript months start at 0 (0-11 instead of 1-12)
dteDate = new Date(year, month, day);
/*
Javascript Dates are a little too forgiving and will change the date to a reasonable guess if it's invalid. We'll use this to our
advantage by creating the date object and then comparing it to the details we put it. If the Date object is different, then it must
have been an invalid date to start with...
*/
return ((day == dteDate.getDate()) && (month == dteDate.getMonth()) && (year == dteDate.getFullYear()));
}
function validateDate(datestring){
month = substr(datestring, 0, 2);
day = substr(datestring, 2, 2);
year = substr(datestring, 6, 4);
if(isValidDate(month, day, year) == false){
alert("Sorry, " + datestring + " is not a valid date.\nPlease correct this.");
return false;
} else {
return true;
}
}
substr is not a function by itself; you must use string.substr(start_index, length).
Since the JavaScript substr method only takes two parameters, not three, this causes execution to halt at the first substr line, and you'll never get output from that function.
I found this by opening Firebug when running your code in a test HTML page. I highly recommend using Firebug for JavaScript debugging.
Try this in your validateDate function, or something similar:
month = datestring.substr(0, 2);
day = datestring.substr(3, 2);
year = datestring.substr(6, 4);
substr is not defined... you need
datestring.substr(0, 2);
you also have a problem with your second substring- it should start at character 3:
day = substr(datestring, 3, 2);
and, month really should be (month - 1) when you create your date
Looking at your code, your date format is "MMDD__YYYY". So your function needs to be as follows:
function isValidDate(month, day, year){
/*
Purpose: return true if the date is valid, false otherwise
Arguments: day integer representing day of month
month integer representing month of year
year integer representing year
Variables: dteDate - date object
*/
var dteDate;
//set up a Date object based on the day, month and year arguments
//javascript months start at 0 (0-11 instead of 1-12)
dteDate = new Date(year, month, day);
alert(d)
/*
Javascript Dates are a little too forgiving and will change the date to a reasonable guess if it's invalid. We'll use this to our
advantage by creating the date object and then comparing it to the details we put it. If the Date object is different, then it must
have been an invalid date to start with...
*/
return ((day == dteDate.getDate()) && (month == dteDate.getMonth()) && (year == dteDate.getFullYear()));
}
function validateDate(datestring){
month = datestring.substring(0, 2);
day = datestring.substring(2, 4);
year = datestring.substring(6, 10);
alert(year)
if(isValidDate(month, day, year) == false){
alert("Sorry, " + datestring + " is not a valid date.\nPlease correct this.");
return false;
} else {
return true;
}
}
validateDate("0202__2010");
If your date is in a more regular format, you can do the following to test if ((new Date("MM/DD/YYYY")) != "Invalid Date")