If you are unable to create a new account, please email support@bspsoftware.com

 

News:

MetaManager - Administrative Tools for IBM Cognos
Pricing starting at $2,100
Download Now    Learn More

Main Menu

Java script to calculate the date difference between 2 date values

Started by Brunomalmsteen, 31 Oct 2016 12:54:16 PM

Previous topic - Next topic

Brunomalmsteen

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!

bdbits

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.

dougp

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;
}
})

Brunomalmsteen

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!!!