Hi there,
I have the following code to calculate the diff between two dates in JavaScript:
<script type="text/javascript">
function validateDate()
{
var fW = (typeof getFormWarpRequest == "function" ?getFormWarpRequest() : document.forms["formWarpRequest"]);
if ( !fW || fW == undefined)
{ fW = ( formWarpRequest_THIS_ ?formWarpRequest_THIS_ : formWarpRequest_NS_ );
}
//Get the prompt values for FromDate & ToDate
var FromDate = fW.txtDatep_ReportFromDt.value;
var ToDate = fW.txtDatep_ReportToDt.value;
//Parse date strings
var new_frm_date = Date.parse(FromDate);
var new_to_date = Date.parse(ToDate);
//Calculate milliseconds in one day
var one_day = (1000 * 60 * 60 * 24);
//Calculate difference between two dates in milliseconds and dats
var difference_ms = Math.abs(new_frm_date - new_to_date);
var difference_days = Math.round(difference_ms/one_day);
if(difference_days>90)
{alert('Dates cannot be more that 90 days apart.');}
else
{alert(Okay);}
}
</script>
The script is not working at all. I did a test and tried to print the var new_frm_date and I getting "Nan" value, which means that the date.parse is not working.
Any tips?
Environment: Cognos 10.2.2
Browser: IE 11
Thanks!
Use your browser debugging tools to step through the code (typically F12). I would break at the first var declaration, then inspect what is in the various references to be sure they are valid and what is expected, e.g. fW, txtDatep_ReportFromDt and its .value, etc. You can use the javascript console to test out your expressions.
Here's what I use.
Date.prototype.dateDiff = function(interval, dt2, firstdow, cal){
// return the number of intervals crossed
// 11:01 to 11:59 is 0 hours
// 10:59 to 11:01 is 1 hour
// When computing for days, if hours are used, the utc offset for each
// date must be used, otherwise 1/1/2009 to 7/1/2009 returns one
// hour short because we set our clocks an hour ahead in the
// spring. This may equate to losing a day, week, or month in
// the calculation.
var dt1 = new Date(this);
if (!interval || !dt1 || !dt2) return;
var v, s = 1, m = 1, h = 1, dd = 1, i = interval;
// if the user wants workdays, but didn't provide a calendar, create a generic calendar
//if (i == "workday" || i == "w") {
if (!cal) {
cal = new Object();
cal.isHoliday = function () { return false; };
}
//}
// if the calendar doesn't have an isHoliday() method, create a generic one
if (typeof cal.isHoliday == "undefined") {
cal.isHoliday = function () { return false; };
}
// default firstdow to Sunday
if (!firstdow || isNaN(firstdow)) {
firstdow = 0;
}
firstdow *= 1.0;
//Console.Writeln("ok");
//if(i == "month" || i == "m" || i == "quarter" || i == "q" || i == "year" || i == "y"){
dt1 = new Date(dt1);
dt2 = new Date(dt2);
years = dt2.getFullYear() - dt1.getFullYear();
switch (i) {
case "year" :
case "y" :
v = years;
break;
case "quarter" :
case "q" :
v = Math.floor(dt2.getMonth() / 3) - Math.floor(dt1.getMonth() / 3);
if (years != 0) v += (years * 4);
break;
case "month" :
case "m" :
v = (dt2.getMonth() + 1) - (dt1.getMonth() + 1);
if (years != 0) v += (years * 12);
break;
case "week" :
case "w" :
dt1.setDate(dt1.getDate() - (dt1.getDay() - firstdow) - (dt1.getDay() < firstdow ? 7 : 0));
dt2.setDate(dt2.getDate() - (dt2.getDay() - firstdow) - (dt2.getDay() < firstdow ? 7 : 0));
v = dt1.dateDiff("d", dt2) / 7;
break;
case "workday" :
case "wd" :
v = 0;
if (dt1 == dt2) {
v++;
}
else if (dt1 < dt2) {
for (var dtTemp = new Date(dt1); dtTemp <= dt2; ) {
// don't count weekends or holidays
// Since sunday.getDay() = 0 and saturday.getDay() = 6, date.getDay() % 6 = 0 for both
if (dtTemp.getDay() % 6 != 0 && !cal.isHoliday(dtTemp)) v++;
dtTemp.setDate(dtTemp.getDate() + 1);
}
}
else {
for (var dtTemp = new Date(dt2); dtTemp <= dt1; ) {
if (dtTemp.getDay() % 6 != 0 && !cal.isHoliday(dtTemp)) v--;
dtTemp.setDate(dtTemp.getDate() + 1);
}
}
v--;
break;
case "day" :
case "d" :
// adjust for a difference caused by daylight savings
dt2.setHours(dt2.getHours() + ((dt1.getTimezoneOffset() - dt2.getTimezoneOffset()) / 60));
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous hour break
dt1 -= (dt1 % (1000 * 60 * 60));
dt2 -= (dt2 % (1000 * 60 * 60));
v = (dt2 - dt1) / (1000 * 60 * 60 * 24);
break;
case "hour" :
case "h" :
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous hour break
dt1 -= (dt1 % (1000 * 60 * 60));
dt2 -= (dt2 % (1000 * 60 * 60));
v = (dt2 - dt1) / (1000 * 60 * 60);
break;
case "minute" :
case "n" :
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous minute break
dt1 -= (dt1 % (1000 * 60));
dt2 -= (dt2 % (1000 * 60));
v = (dt2 - dt1) / (1000 * 60);
break;
case "second" :
case "s" :
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous second break
dt1 -= (dt1 % 1000);
dt2 -= (dt2 % 1000);
v = (dt2 - dt1) / 1000;
break;
}
//}
return v;
} // dateDiff
cal is a CustomCalendar object that allows you to define non-work days (holidays).
CustomCalendar: Class.create({
initialize: function() {
_holiday = new Array(); // array of holidays
},
isHoliday: function(dt) {
if (!Date.prototype.isPrototypeOf(dt)) {
return false;
}
if (_holiday.contains(dt.format("mm/dd/yyyy"))) {
return true;
}
else {
return false;
}
},
Add: function (dt) {
// add a holiday to the calendar
if (!Date.prototype.isPrototypeOf(dt)) {
return false;
}
else {
_holiday.push(dt.format("mm/dd/yyyy"));
return true;
}
},
Holidays: function () {
// return an array containing the holidays
return _holiday;
}
})
...and you'll need... (I hope I got all of the dependencies.)
Object.extend = function(destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
};
Class = {
create: function() {
var parent = null, properties = $A(arguments);
if (Object.isFunction(properties[0]))
parent = properties.shift();
function klass() {
this.initialize.apply(this, arguments);
}
Object.extend(klass, Class.Methods);
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
var subclass = function() { };
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
parent.subclasses.push(klass);
}
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
klass.prototype.initialize = Hyperion.emptyFunction;
klass.prototype.constructor = klass;
return klass;
}
};
Object.extend(Array.prototype, {
contains: function (ValueToFind) {
/*
Object Method: Array.contains()
Type: JavaScript
Purpose: Determine if an element with the given value exists in an array
Inputs: object Required an array object
ValueToFind Required the value to find
Returns: A boolean value indicating whether an element with a value
matching the search criteria exists.
Revision History
Date Developer Description
7/31/2008 D. Pulse original
*/
for (var a in this) {
if (this[a] == ValueToFind) return true;
}
for (var i = 0; i < this.length; i++) {
if (this[i] == ValueToFind) return true;
}
return false;
}
});
Object.extend(Date.prototype, {
format: function (DateFormat) {
/*
Object Method: Date.format()
Type: JavaScript
Purpose: Provides a method for formatting dates according to
a specific date format pattern string.
Inputs: object Required a Date object
NumberFormat Required the string pattern defining how to format the number
eg. "mm/dd/yyyy"
Returns: A string containing the formatted date.
Revision History
Date Developer Description
*/
if (!this.isDate()) return "Invalid date";
//if (!this.valueOf())
// return " ";
if (DateFormat == undefined)
return(this.toLocaleDateString());
var d = this;
DateFormat = DateFormat.toLowerCase();
var s = DateFormat.replace(/(yyyy|yy|mmmm|mmm|mm|m|dddd|ddd|dd|d|hh|h|nn|n|ss|s|a\/p|am\/pm)/gi,
function($1) {
switch ($1.toLowerCase()) {
case "am":
case "pm": return $1;
case "yyyy": return d.getFullYear();
case "yy": return d.getFullYear().toString().substr(d.getFullYear().toString().length - 2);
case "mmmm": return Application.MonthName[d.getMonth()];
case "mmm": return Application.MonthName[d.getMonth()].substr(0, 3);
case "mm": return (d.getMonth() + 1).toPaddedString(2);
case "m": return (d.getMonth() + 1);
case "dddd": return Application.WeekdayName[d.getDay()];
case "ddd": return Application.WeekdayName[d.getDay()].substr(0, 3);
case "dd": return d.getDate().toPaddedString(2);
case "d": return d.getDate();
case "hh":
h = d.getHours() % 24;
if (DateFormat.search(/am\/pm/i) != -1 || DateFormat.search(/a\/p/i) != -1) {
h %= 12;
h = (h == 0) ? 12 : h;
}
return h.toPaddedString(2);
case "h":
h = d.getHours() % 24;
if (DateFormat.search(/am\/pm/i) != -1 || DateFormat.search(/a\/p/i) != -1) {
h %= 12;
h = (h == 0) ? 12 : h;
}
return h;
case "nn": return d.getMinutes().toPaddedString(2);
case "n": return d.getMinutes();
case "ss": return d.getSeconds().toPaddedString(2);
case "s": return d.getSeconds();
case "a/p": return $1 == $1.toLowerCase() ? (d.getHours() < 12 ? "a" : "p") : (d.getHours() < 12 ? "a" : "p").toUpperCase();
case "am/pm": return $1 == $1.toLowerCase() ? (d.getHours() < 12 ? "am" : "pm") : (d.getHours() < 12 ? "am" : "pm").toUpperCase();
default: return $1;
}
}
);
return s;
}
});
Object.extend(Number.prototype, {
toPaddedString: function(length, radix) {
var string = this.toString(radix || 10);
return '0'.times(length - string.length) + string;
}
})
Quote from: dougp on 31 Oct 2016 01:46:37 PM
Here's what I use.
Date.prototype.dateDiff = function(interval, dt2, firstdow, cal){
// return the number of intervals crossed
// 11:01 to 11:59 is 0 hours
// 10:59 to 11:01 is 1 hour
// When computing for days, if hours are used, the utc offset for each
// date must be used, otherwise 1/1/2009 to 7/1/2009 returns one
// hour short because we set our clocks an hour ahead in the
// spring. This may equate to losing a day, week, or month in
// the calculation.
var dt1 = new Date(this);
if (!interval || !dt1 || !dt2) return;
var v, s = 1, m = 1, h = 1, dd = 1, i = interval;
// if the user wants workdays, but didn't provide a calendar, create a generic calendar
//if (i == "workday" || i == "w") {
if (!cal) {
cal = new Object();
cal.isHoliday = function () { return false; };
}
//}
// if the calendar doesn't have an isHoliday() method, create a generic one
if (typeof cal.isHoliday == "undefined") {
cal.isHoliday = function () { return false; };
}
// default firstdow to Sunday
if (!firstdow || isNaN(firstdow)) {
firstdow = 0;
}
firstdow *= 1.0;
//Console.Writeln("ok");
//if(i == "month" || i == "m" || i == "quarter" || i == "q" || i == "year" || i == "y"){
dt1 = new Date(dt1);
dt2 = new Date(dt2);
years = dt2.getFullYear() - dt1.getFullYear();
switch (i) {
case "year" :
case "y" :
v = years;
break;
case "quarter" :
case "q" :
v = Math.floor(dt2.getMonth() / 3) - Math.floor(dt1.getMonth() / 3);
if (years != 0) v += (years * 4);
break;
case "month" :
case "m" :
v = (dt2.getMonth() + 1) - (dt1.getMonth() + 1);
if (years != 0) v += (years * 12);
break;
case "week" :
case "w" :
dt1.setDate(dt1.getDate() - (dt1.getDay() - firstdow) - (dt1.getDay() < firstdow ? 7 : 0));
dt2.setDate(dt2.getDate() - (dt2.getDay() - firstdow) - (dt2.getDay() < firstdow ? 7 : 0));
v = dt1.dateDiff("d", dt2) / 7;
break;
case "workday" :
case "wd" :
v = 0;
if (dt1 == dt2) {
v++;
}
else if (dt1 < dt2) {
for (var dtTemp = new Date(dt1); dtTemp <= dt2; ) {
// don't count weekends or holidays
// Since sunday.getDay() = 0 and saturday.getDay() = 6, date.getDay() % 6 = 0 for both
if (dtTemp.getDay() % 6 != 0 && !cal.isHoliday(dtTemp)) v++;
dtTemp.setDate(dtTemp.getDate() + 1);
}
}
else {
for (var dtTemp = new Date(dt2); dtTemp <= dt1; ) {
if (dtTemp.getDay() % 6 != 0 && !cal.isHoliday(dtTemp)) v--;
dtTemp.setDate(dtTemp.getDate() + 1);
}
}
v--;
break;
case "day" :
case "d" :
// adjust for a difference caused by daylight savings
dt2.setHours(dt2.getHours() + ((dt1.getTimezoneOffset() - dt2.getTimezoneOffset()) / 60));
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous hour break
dt1 -= (dt1 % (1000 * 60 * 60));
dt2 -= (dt2 % (1000 * 60 * 60));
v = (dt2 - dt1) / (1000 * 60 * 60 * 24);
break;
case "hour" :
case "h" :
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous hour break
dt1 -= (dt1 % (1000 * 60 * 60));
dt2 -= (dt2 % (1000 * 60 * 60));
v = (dt2 - dt1) / (1000 * 60 * 60);
break;
case "minute" :
case "n" :
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous minute break
dt1 -= (dt1 % (1000 * 60));
dt2 -= (dt2 % (1000 * 60));
v = (dt2 - dt1) / (1000 * 60);
break;
case "second" :
case "s" :
dt1 = Date.parse(dt1);
dt2 = Date.parse(dt2);
// truncate the date value to the previous second break
dt1 -= (dt1 % 1000);
dt2 -= (dt2 % 1000);
v = (dt2 - dt1) / 1000;
break;
}
//}
return v;
} // dateDiff
cal is a CustomCalendar object that allows you to define non-work days (holidays).
CustomCalendar: Class.create({
initialize: function() {
_holiday = new Array(); // array of holidays
},
isHoliday: function(dt) {
if (!Date.prototype.isPrototypeOf(dt)) {
return false;
}
if (_holiday.contains(dt.format("mm/dd/yyyy"))) {
return true;
}
else {
return false;
}
},
Add: function (dt) {
// add a holiday to the calendar
if (!Date.prototype.isPrototypeOf(dt)) {
return false;
}
else {
_holiday.push(dt.format("mm/dd/yyyy"));
return true;
}
},
Holidays: function () {
// return an array containing the holidays
return _holiday;
}
})
...and you'll need... (I hope I got all of the dependencies.)
Object.extend = function(destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
};
Class = {
create: function() {
var parent = null, properties = $A(arguments);
if (Object.isFunction(properties[0]))
parent = properties.shift();
function klass() {
this.initialize.apply(this, arguments);
}
Object.extend(klass, Class.Methods);
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
var subclass = function() { };
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
parent.subclasses.push(klass);
}
for (var i = 0; i < properties.length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
klass.prototype.initialize = Hyperion.emptyFunction;
klass.prototype.constructor = klass;
return klass;
}
};
Object.extend(Array.prototype, {
contains: function (ValueToFind) {
/*
Object Method: Array.contains()
Type: JavaScript
Purpose: Determine if an element with the given value exists in an array
Inputs: object Required an array object
ValueToFind Required the value to find
Returns: A boolean value indicating whether an element with a value
matching the search criteria exists.
Revision History
Date Developer Description
7/31/2008 D. Pulse original
*/
for (var a in this) {
if (this[a] == ValueToFind) return true;
}
for (var i = 0; i < this.length; i++) {
if (this[i] == ValueToFind) return true;
}
return false;
}
});
Object.extend(Date.prototype, {
format: function (DateFormat) {
/*
Object Method: Date.format()
Type: JavaScript
Purpose: Provides a method for formatting dates according to
a specific date format pattern string.
Inputs: object Required a Date object
NumberFormat Required the string pattern defining how to format the number
eg. "mm/dd/yyyy"
Returns: A string containing the formatted date.
Revision History
Date Developer Description
*/
if (!this.isDate()) return "Invalid date";
//if (!this.valueOf())
// return " ";
if (DateFormat == undefined)
return(this.toLocaleDateString());
var d = this;
DateFormat = DateFormat.toLowerCase();
var s = DateFormat.replace(/(yyyy|yy|mmmm|mmm|mm|m|dddd|ddd|dd|d|hh|h|nn|n|ss|s|a\/p|am\/pm)/gi,
function($1) {
switch ($1.toLowerCase()) {
case "am":
case "pm": return $1;
case "yyyy": return d.getFullYear();
case "yy": return d.getFullYear().toString().substr(d.getFullYear().toString().length - 2);
case "mmmm": return Application.MonthName[d.getMonth()];
case "mmm": return Application.MonthName[d.getMonth()].substr(0, 3);
case "mm": return (d.getMonth() + 1).toPaddedString(2);
case "m": return (d.getMonth() + 1);
case "dddd": return Application.WeekdayName[d.getDay()];
case "ddd": return Application.WeekdayName[d.getDay()].substr(0, 3);
case "dd": return d.getDate().toPaddedString(2);
case "d": return d.getDate();
case "hh":
h = d.getHours() % 24;
if (DateFormat.search(/am\/pm/i) != -1 || DateFormat.search(/a\/p/i) != -1) {
h %= 12;
h = (h == 0) ? 12 : h;
}
return h.toPaddedString(2);
case "h":
h = d.getHours() % 24;
if (DateFormat.search(/am\/pm/i) != -1 || DateFormat.search(/a\/p/i) != -1) {
h %= 12;
h = (h == 0) ? 12 : h;
}
return h;
case "nn": return d.getMinutes().toPaddedString(2);
case "n": return d.getMinutes();
case "ss": return d.getSeconds().toPaddedString(2);
case "s": return d.getSeconds();
case "a/p": return $1 == $1.toLowerCase() ? (d.getHours() < 12 ? "a" : "p") : (d.getHours() < 12 ? "a" : "p").toUpperCase();
case "am/pm": return $1 == $1.toLowerCase() ? (d.getHours() < 12 ? "am" : "pm") : (d.getHours() < 12 ? "am" : "pm").toUpperCase();
default: return $1;
}
}
);
return s;
}
});
Object.extend(Number.prototype, {
toPaddedString: function(length, radix) {
var string = this.toString(radix || 10);
return '0'.times(length - string.length) + string;
}
})
Doug, thanks for the tips. I will try that. I tried my script at home, with my own Cognos Server and it was working. I noticed that the difference was the Date format. AT home, I have, for instance, Dec 4, 2016. At work I have , 04-Dec-16. I found that Date.Parse was not able to parse that format to a valid Date object, and then, my script was not working.
Anyway, I will give a try using yours, because the logic seems to be more interesting and covering several different aspects of calendar/business days. I will give a try and let you know!!!