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.
Related
var checkDate = new Date("22/22/2222");
When I check in IE 11 it convert to Wed Oct 22 00:00:00 EDT 2223 so my next line fails
if (checkDate != 'Invalid Date')
How to fix it?
As you've passed in an invalid date format (as far as the ECMA spec is concerned), the browser is free to choose to interpret it how it wishes. It seems IE thinks it can deal with it:
The function first attempts to parse the format of the String according to the rules (including extended years) called out in Date Time String Format (20.3.1.16). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
If you're going to pass in strange formats, you're either going to need to validate them yourself or use a library that can do so better than the browsers can.
Months and days can "wrap" in JavaScript. One way to test if the date is legal is to see if the output date corresponds to the original input string. If it doesn't, then it wrapped.
function check(inputString) {
var checkDate = new Date(inputString);
// Get month, day, and year parts, assuming
// you don't have them already
var arr = inputString.split('/');
var isMonthWrapped = +arr[0] !== checkDate.getMonth() + 1;
var isDayWrapped = +arr[1] !== checkDate.getDate();
var isYearWrapped = +arr[2] !== checkDate.getFullYear();
console.log("Parts", +arr[0], +arr[1], +arr[2]);
console.log("Results", checkDate.getMonth() + 1, checkDate.getDate(), checkDate.getFullYear());
console.log("Wrapped?", isMonthWrapped, isDayWrapped, isYearWrapped);
var isLegal = checkDate !== 'Invalid Date' && !isMonthWrapped && !isDayWrapped && !isYearWrapped;
document.body.innerHTML += inputString + ': ' + (isLegal ? 'Legal' : 'Illegal') + '<br>';
};
check("22/22/2222");
check("12/12/2222");
I think that moment.js http://momentjs.com/ is a complete and good package about dates.
You could add string date and format.
moment("12/25/1995", "MM/DD/YYYY");
And you could check if date is valid.
moment("not a real date").isValid();
See documentation
http://momentjs.com/docs/#/parsing/string-format/
You should break up your string and parse Each date to integers individually. It will be much safer.
Do something like this
var dateString = "22/22/2222";
dateString.indexOf("/");
var day = parseInt(dateString.slice(0,dateString.indexOf("/")));
dateString = dateString.slice(1+dateString.indexOf("/"), dateString.length);
var month = parseInt(dateString.slice(0,dateString.indexOf("/")))
dateString = dateString.slice(1+dateString.indexOf("/"), dateString.length);
var year = parseInt(dateString);
console.log(day, month, year);
var date = new Date(0);
if(month>12) console.log("hey this is totally not a valid month maaaan!")
date.setDate(day);
date.setMonth(month);
date.setYear(year);
console.log(date);
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 am facing some problem in comparing dates in javascript.
I have dates in "1-Dec-2014" & "19-Nov-2014" format.
While I compared the dates like
var stDate='19-Nov-2014';
var endDate='1-Dec-2014';
if(stDate < endDate){
console.log('Hi');
}else{
console.log('Bye');
}
In out put it shows me "Bye", but it should be "Hi".
What I observed it this comparison compares the date (initial argument) in respective dates.
I am very new to javascript . I am not getting any way to solve this .
Please help me.
Currently you are only comparing two strings. You should compare the dates like this:
new Date(stDate) < new Date(endDate)
var stDate='19-Nov-2014';
var endDate='1-Dec-2014';
if(new Date(stDate) < new Date(endDate)){
console.log('Hi');
}else{
console.log('Bye');
}
Just like #Arun P Johnny said, you are comparing Strings instead of actual dates. You need to convert you date to Date objects before comparing them. Check this out.
As noted in other answers, you need to convert the strings to Date objects. The best way to do that is to parse the strings using a function like:
/* Return a Date object or NaN given a string in d, MMM y or dd-MMM-yyyy format
** e.g. 5 Dec, 2014
** Avoid conversion of two digit dates to 20th century
** Returns NaN if string is not a valid date
*/
function parseDMMMY(s) {
var b = s.match(/\w+/g);
var months = {jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
jul:6, aug:7, sep:8, oct:9, nov:10, dec:11};
if (b) {
var d = new Date();
d.setHours(0,0,0,0);
d.setFullYear(b[2], months[b[1].toLowerCase()], b[0]);
}
return b && d.getFullYear() == b[2] && d.getDate() == b[0]? d : NaN;
}
This also treats dates like 1-1-19 as in year 19, rather than 1919 which may happen if the values are passed directly to the Date constructor rather than using the set* methods.
Now you can do:
var stDate = parseDMMMY('19-Nov-2014');
var endDate = parseDMMMY('1-Dec-2014');
To handle dates correctly i'll quote Pavel Hodek
The best you can do is use the ISO format: YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS
For example:
new Date('2011-04-11')
or
new Date('2011-04-11T11:51:00')
For more Info: MDN | Date
Edit:
For old Internet Explorer compatibility (IE versions less than 9 do not support ISO format in Date constructor), you should split datetime string representation to it's parts and then you can use constructor using datetime parts, e.g.: new Date('2011', '04' - 1, '11', '11', '51', '00')
Note that the number of the month must be 1 less.
Important note:
The "ISO format" solution doesn't work 100% time. String are sometimes parsed as UTC and sometimes as localtime (based on browser vendor and version). Calling toString returns the local time therefore depending on the users timezone in some cases new Date('2011-04-11') will give you 2011-04-10.
Chrome behaves the same as Internet Explorer 9 and Firefox behaves the same as Internet Explorer 10+.
Safe solution is passing string value with Z to be parsed as UTC value e.g. new Date('2011-04-11T10:20:30Z'). Best practice should always be to store dates as UTC and make computations as UTC. Only for presentation they should be presented as local time.
Once you have both dates (after parsing and/or using constructor) you can safely compare them.
function ValidateDate() {
var SDate = document.getElementById('<%=sdate.ClientID%>').value;
var EDate = document.getElementById('<%=edate.ClientID%>').value;
var sdate = new Date(stDate);
var Edate = new Date(endDate);
var alertReason1 = 'To Date must be greater than or equal to From Date.'
//var endDate = new Date(EDate);
//var startDate = new Date(SDate);
if (SDate != "" && EDate != "" && Edate > sdate ) {
alert(alertReason1);
return false;
}
}
I have a date in this format: dd.mm.yyyy
When I instantiate a JavaScript date with it, it gives me a NaN
In c# I can specify a date format, to say: here you have my string, it's in this format, please make a Datetime of it.
Is this possible in JavaScript too? If not, is there an easy way?
I would prefer not to use a substring for day, substring for month etc. because my method must also be capable of german, italian, english etc. dates.
You will need to create a function to extract the date parts and use them with the Date constructor.
Note that this constructor treats months as zero based numbers (0=Jan, 1=Feb, ..., 11=Dec).
For example:
function parseDate(input) {
var parts = input.match(/(\d+)/g);
// note parts[1]-1
return new Date(parts[2], parts[1]-1, parts[0]);
}
parseDate('31.05.2010');
// Mon May 31 2010 00:00:00
Edit: For handling a variable format you could do something like this:
function parseDate(input, format) {
format = format || 'yyyy-mm-dd'; // default format
var parts = input.match(/(\d+)/g),
i = 0, fmt = {};
// extract date-part indexes from the format
format.replace(/(yyyy|dd|mm)/g, function(part) { fmt[part] = i++; });
return new Date(parts[fmt['yyyy']], parts[fmt['mm']]-1, parts[fmt['dd']]);
}
parseDate('05.31.2010', 'mm.dd.yyyy');
parseDate('31.05.2010', 'dd.mm.yyyy');
parseDate('2010-05-31');
The above function accepts a format parameter, that should include the yyyy mm and dd placeholders, the separators are not really important, since only digits are captured by the RegExp.
You might also give a look to DateJS, a small library that makes date parsing painless...
It's easy enough to split the string into an array and pass the parts directly to the Date object:
var str = "01.01.2010";
var dmy = str.split(".");
var d = new Date(dmy[2], dmy[1] - 1, dmy[0]);
There is no built in way to manipulate dates the way you would like.
The jQuery-UI datepicker has the functionality you want, I'm sure many other libraries have something similar.
$.datepicker.parseDate('dd.mm.yy', '31.12.2007');
t="01.01.1970"
parts = t.split(".");
for(var i = 0; i < parts.length; i++) parts[i] = parseInt(parts[i], 10);
new Date(parts[2], parts[1]-1, parts[0]);
Date defined as (Year, Month, Date)
Date()'s month parameter takes Month in Zero based index. January = 0, february = 1, march = 2... etc
Parsing the string to an int isn't necessary, but I dislike passing strings into functions and just hoping that JavaScript will "get it"... Sort of like how some people prefer ===
Building on CMS answer, I created this function to deal with a variable format
function parseDate(input, format) {
format = format || 'yyyy-mm-dd'; // default format
//Change from PHP date format to JS
if (format == 'd/m/Y') {
format = 'dd/mm/yyyy';
}
if (format == 'd/m/Y H:i:s') {
format = 'dd/mm/yyyy hh:ii:ss';
}
let date = NaN;
if (format == 'dd/mm/yyyy') {
let parts = input.match(/(\d+)/g),
i = 0, fmt = {};
// extract date-part indexes from the format
format.replace(/(yyyy|dd|mm)/g, function(part) { fmt[part] = parts[i++]; });
//create date for new format
let createdDate = new Date(fmt['yyyy'], fmt['mm']-1, fmt['dd']);
//check if dates are equal by comparing parts. The issue I had here was
//when I passed an invalid value for month, the output was adjustement to
//accomodate for the extra months
if (
createdDate.getFullYear() == fmt['yyyy'] &&
createdDate.getMonth() == (fmt['mm']-1) &&
createdDate.getDate() == fmt['dd']
) {
date = createdDate;
}
}
//same but taking into account hours minute and seccond
if (format == 'dd/mm/yyyy hh:ii:ss') {
let parts = input.match(/(\d+)/g),
i = 0, fmt = {};
// extract date-part indexes from the format
format.replace(/(yyyy|dd|mm|hh|ii|ss)/g,
function(part) { fmt[part] = parts[i++]; });
let createdDate = new Date(
fmt['yyyy'], fmt['mm']-1, fmt['dd'],
fmt['hh'], fmt['ii'], fmt['ss']
);
if (
createdDate.getFullYear() == fmt['yyyy'] &&
createdDate.getMonth() == (fmt['mm']-1) &&
createdDate.getDate() == fmt['dd'] &&
createdDate.getHours() == fmt['hh'] &&
createdDate.getMinutes() == fmt['ii'] &&
createdDate.getSeconds() == fmt['ss']
) {
date = createdDate;
}
}
return date;
}
Modified version of the accepted answer which supports value and format without 'dd' and uppercase format
function parseDate(input, format) {
format = (format || 'yyyy-mm-dd').toLowerCase(); // default format
var parts = input.match(/(\d+)/g),
i = 0, fmt = {};
// extract date-part indexes from the format
format.replace(/(yyyy|dd|mm)/g, function(part) { fmt[part] = i++; });
return new Date([parts[fmt['yyyy']], parts[fmt['mm']], parts[fmt['dd']]].filter(x => x !== undefined).join('-'));
}
parseDate('10/2018', 'MM/YYYY')
I'm comparing dates with something like this:
var dt = new Date();
dt.setDate("17");
dt.setMonth(06);
dt.setYear("2009");
var date = new Date();
console.log("dt(%s) == date(%s) == (%s)", dt, date, (dt == date) );
if( now == dt ) {
....
}
The string values are dynamic of course.
In the logs I see:
dt(Fri Jul 17 2009 18:36:56 GMT-0500 (CST)) == date(Fri Jul 17 2009 18:36:56 GMT-0500 (CST) == (false)
I tried .equals() but it didn't work ( I was trying the Java part of JavaScript :P )
How can I compare these dates so they return true?
The following code should solve your problem:
(myDate.getTime() == myOtherDate.getTime())
The problem is that when you write:
(myDate == myOtherDate)
...you're actually asking "Is myDate pointing to the same object that myOtherDate is pointing to?", not "Is myDate identical to myOtherDate?".
The solution is to use getTime to obtain a number representing the Date object (and since getTime returns the number of milliseconds since epoch time, this number will be an exact representation of the Date object) and then use this number for the comparison (comparing numbers will work as expected).
The problem with your code is that you are comparing time/date part instead of only the date.
Try this code:
var myDate = new Date();
myDate.setDate(17);
myDate.setMonth(7);
myDate.setYear(2009);
//Delay code - start
var total = 0;
for(var i=0; i<10000;i++)
total += i;
//Delay code - end
var now = new Date();
console.log(now.getTime() == myDate.getTime());
If you keep the for loop code (identified by 'Delay code -start'), console will show 'false' and if you remove the for loop code, console will log 'true' even though in both the cases myDate is 7/17/2009 and 'now' is 7/17/2009.
The problem is that JavaScript date object stores both date and time. If you only want to compare the date part, you have to write the code.
function areDatesEqual(date1, date2)
{
return date1.getFullYear() == date2.getFullYear()
&& date1.getMonth() == date2.getMonth()
&& date1.getDate() == date2.getDate();
}
This function will print 'true' if the two javascript 'date part' is equal ignoring the associated time part.
=> (myDate.getTime() == myOtherDate.getTime())
(myDate == myOtherDate) does not work, it compares the two objects (pointers) instead of the value that they contain. Use getTime to get integer representation of Date and then compare.