I have a problem that seems so senseless that I'm sure I'm missing something really stupid.
I have the following Javascript function that validates a date:
function validateDate(date){
var re = /\b\d{1,2}[\/-]\d{1,2}[\/-]\d{4}\b/;
if(!re.test(date))
return false;
var separator = (date.indexOf("/") != -1) ? "/" : "-";
var aux = date.split(separator);
var day = parseInt(aux[0]);
var month = parseInt(aux[1]);
var year = parseInt(aux[2]);
alert(aux[0]+" "+aux[1]+" "+aux[2]);
var dateTest = new Date(year,month-1,day);
alert(dateTest); //2nd alert
if(dateTest.getDate() != day)
return false;
if(dateTest.getMonth()+1!= month)
return false;
if(dateTest.getFullYear() != year)
return false;
return true;
}
the first alert always shows the correct values.
if the incoming date is for example 05/07/2011, everything works fine. The second alert shows "Tue Jul 5 00:00:00 UTC+0200 2011" which is right.
but now, if i change the date month to august or september, the created date is wrong. for example, with date 05/08/2011, the second alert will show "Sun Dec 5 00:00:00 UTC+0100 2010".
anyone knows what could be happening??
Make sure you supply a radix to parseInt. If you don't, it will "guess" based on the string. In this case, your 08 is being parsed as an octal value because of the prefixed zero and you get 0 back.
var day = parseInt(aux[0], 10);
var month = parseInt(aux[1], 10);
var year = parseInt(aux[2], 10);
Supplying a base ten number will get you the correct result.
//Parsing numbers:
parseInt("06"); // 6, valid octal
parseInt("07"); // 7, valid octal
parseInt("08"); // 0, invalid octal
parseInt("09"); // 0, invalid octal
parseInt("10"); // 10, parsed as decimal
parseInt("11"); // 11, parsed as decimal
parseInt("12"); // 12, parsed as decimal
Related
I want to validate dates by Javascript and found this nice answer:
https://stackoverflow.com/a/1353711/3391783
but when i try to use it to validate dates, it seems like Javascript is auto-correcting my date by taking the closest valid date. so this will return true even though 2014-11-31 is not a valid date (Javascript months start at 0, so 10 equals November):
function isValidDate(d) {
if ( Object.prototype.toString.call(d) !== "[object Date]" )
return false;
return !isNaN(d.getTime());
}
var test_date = new Date(2014, 10, 31);
console.log( test_date );
console.log( isValidDate(test_date) );
seems like creating the Date is automatically switching it to 2014-12-01 which is a correct date.
but I would like to be able to validate user input without changing it.
So how can i create an invalid new Date() in Javascript?
Or is there a much simpler way to do this?
You can use the auto-correction in the Date object to validate the date. Just check the input against what you have in the Date object:
var y = 2014, m = 10, d = 31;
var test_date = new Date(y, m, d);
var valid =
test_date.getFullYear() == y &&
test_date.getMonth() == m &&
test_date.getDate() == d;
document.write(valid);
When it comes to handling dates in JavaScript, I'm a big fan of Moment.js. As you can see here, they do a good job of validating dates: http://momentjs.com/docs/#/parsing/is-valid/
new Date(2013, 25, 14).toString(); // "Sat Feb 14 2015 00:00:00 GMT-0500 (EST)"
moment([2015, 25, 35]).format(); // 'Invalid date'
Here's a function I wrote a while back that demonstrates Guffa's solution.
function isValidDate(checkDate) {
if(!/\d\d\/\d\d\/\d\d\d\d/.test(checkDate)) {
return false; // checkDate is not formatted as ##/##/####
} else {
// split checkDate into three pieces
var strMM = checkDate.split('/')[0];
var strDD = checkDate.split('/')[1];
var strYYYY = checkDate.split('/')[2];
// create new Date() object from split pieces
var strDateCheck = new Date(strYYYY,(strMM - 1),strDD);
// evaluate each piece of resulting date object against each corresponding piece of checkDate
if(((strDateCheck.getMonth() + 1) == strMM) && (strDateCheck.getDate() == strDD) && (strDateCheck.getFullYear() == strYYYY)) {
/* if you wish, add additional validation constraints here */
return true; // all three pieces match exactly
} else {
return false; // at least one piece did not match
}
}
}
I'm trying to return a date in format i.e(12-5-2013) to the variable 'returningOn' by adding 'stayingFor' days number to the formatted 'dateObj' in the same format.
But i seem to be getting bizarre values when i do some console.logs. Why is this? Also, What date format is the last variable in?
var leavingOn = $('#leavingOn') != 'undefined' ? $('#leavingOn').val() : '12-7-2013';
var stayingFor = $('#stayingFor') != 'undefined' ? $('#stayingFor').val() : 7 ;
var splitDate = leavingOn.split('-');
var dateObj = new Date(Number(splitDate[0]), Number(splitDate[1]) -1, Number(splitDate[2]));
var returningOn = dateObj.setDate(dateObj.getDate() + stayingFor);
console.log(splitDate); // ["2013", "11", "14"]
console.log(leavingOn); // 2013-11-14
console.log(stayingFor); // 7
console.log(dateObj); // Fri Jul 25 2014 22:00:07 GMT+0100 (GMT Daylight Time)
console.log(returningOn); // 1406322007249
I think the stayingFor variable needs to be converted to an integer. Try:
stayingFor = parseInt(stayingFor);
i have a weird problem in my javascript, take a look at my code below:
dateParts = document.getElementById('date').value.split('/');
newDays = 14;
year = dateParts[2];
month = parseInt(dateParts[1]) - 1;
day = parseInt(dateParts[0]) + parseInt(newDays);
alert(dateParts[0]+" + "+newDays+" = "+day);
and assume document.getElementById('date') = 07/01/2013
the calculation will give a correct result = 07 + 14 = 21
the calculation work fine at all date, except for 08/01/2013 / 09/01/2013
which the result is 08 + 14 = 14, any idea whats wrong here?
Your numbers are treated as octals, since you haven't used radix within parseInt()s. You need to adjust your parseInt()s like this:
month = parseInt(dateParts[1], 10) - 1;
day = parseInt(dateParts[0], 10) + parseInt(newDays, 10);
The leading 0 in 08 and 09 is causing JavaScript to assume the number is octal. Since those are not valid octal values, it treats them as 0. See this question for more details.
You should always use a radix when calling parseInt to avoid this problem.
the function is The parseInt(str, redix), if the value in the parseInt start with 0, it is assumed the radix is 8 so '09', '08' is invalid and the function returns 0. You need to call the function like parseInt('08', 10) to get the correct value.
I have this - Tue, 03 Apr 2012 05:00:33 GMT
Need this - 20120323111106
Google has failed me, I think I just don't know exactly what im searching for so I kept it simple here with the question.
EDIT: The dates do not match obviously, just looking to get it in that format.
Good answer (later edited):
I think this is what you are looking for :
function addZero(val){
if (parseInt(val) < 10) return "0" + val;
return val;
}
var dt = new Date("Tue, 03 Apr 2012 05:00:33 GMT");
console.log(dt.getFullYear() + addZero(dt.getMonth()) + addZero(dt.getDay()) + addZero(dt.getHours()) + addZero(dt.getMinutes()) + addZero(dt.getSeconds()))
Initial wrong answer :
var dt = new Date("Tue, 03 Apr 2012 05:00:33 GMT")
var miliseconds = dt.getTime();
I've tested it and my computer converted it automatically to GMT +3 (my timezone), you can play with that according to your timezone.
Writing a function to parse a string should work for you. By the looks of it, any date string that you currently have will be the same length. If this is the case this should be relatively easy. Just make sure your strings are in this format before you pass them in as arguments.
function parse(string) {
var out = "yyyymmddhhmmss"
out.charAt(0) = string.charAt(13);
out.charAt(1) = string.charAt(14);
out.charAt(2) = string.charAt(15);
out.charAt(3) = string.charAt(16);
//if else statements for each month converting to numbers
if (string.substring(9,12).equals("Apr")) {
out.charAt(4) = '0';
out.charAt(5) = '4';
}
out.charAt(6) = string.charAt(18);
out.charAt(7) = string.charAt(19);
...etc for the remaining values
return out
}
My numbers for character indices may be off, but if you use this idea, it should set you straight. Define a function and pass in the dates in the format you have, and out will come the dates in the format you want.
I have two dates 18-Aug-2010 and 19-Aug-2010 of this format. How to find whether which date is greater?
You will need to create a custom parsing function to handle the format you want, and get date objects to compare, for example:
function customParse(str) {
var months = ['Jan','Feb','Mar','Apr','May','Jun',
'Jul','Aug','Sep','Oct','Nov','Dec'],
n = months.length, re = /(\d{2})-([a-z]{3})-(\d{4})/i, matches;
while(n--) { months[months[n]]=n; } // map month names to their index :)
matches = str.match(re); // extract date parts from string
return new Date(matches[3], months[matches[2]], matches[1]);
}
customParse("18-Aug-2010");
// "Wed Aug 18 2010 00:00:00"
customParse("19-Aug-2010") > customParse("18-Aug-2010");
// true
You can do the parsing manually, for your given format, but I'd suggest you use the date.js library to parse the dates to Date objects and then compare.
Check it out, its awesome!
And moreover, its a great addition to your js utility toolbox.
The native Date can parse "MMM+ dd yyyy", which gives:
function parseDMY(s){
return new Date(s.replace(/^(\d+)\W+(\w+)\W+/, '$2 $1 '));
}
+parseDMY('19-August-2010') == +new Date(2010, 7, 19) // true
parseDMY('18-Aug-2010') < parseDMY('19-Aug-2010') // true
Firstly, the 'dd-MMM-yyyy' format isn't an accepted input format of the Date constructor (it returns an "invalid date" object) so we need to parse this ourselves. Let's write a function to return a Date object from a string in this format.
function parseMyDate(s) {
var m = ['jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec'];
var match = s.match(/(\d+)-([^.]+)-(\d+)/);
var date = match[1];
var monthText = match[2];
var year = match[3];
var month = m.indexOf(monthText.toLowerCase());
return new Date(year, month, date);
}
Date objects implicitly typecast to a number (milliseconds since 1970; epoch time) so you can compare using normal comparison operators:
if (parseMyDate(date1) > parseMyDate(date2)) ...
Update: IE10, FX30 (and likely more) will understand "18 Aug 2010" without the dashes - Chrome handles either
so Date.parse("18-Aug-2010".replace("/-/g," ")) works in these browsers (and more)
Live Demo
Hence
function compareDates(str1,str2) {
var d1 = Date.parse(str1.replace("/-/g," ")),
d2 = Date.parse(str2.replace("/-/g," "));
return d1<d2;
}