the number of days between two dates
When it comes to calculations OpenClinica offers basic functionality: you can do some calculations with integers and/or reals, but that's it. But in your trial, you may want to display for example the number of days between two dates.
(Before we embark on our journey: if you're looking for this thing, but then with timefields: look here!)
fig. 1: example
how difficult can that be?
You may think "can't we just subtract date2 of date1?". No, unfortunately you can not do any calculations with dates and we will explain why not.
But do not fear: you will see how to do it.
If you can't wait to see it in action, click here for the XL-file.
It looks like this:
fig. 2: the XL
first the script
<div ID="Diff"></div>
<script src="includes/jmesa/jquery.min.js">// for OC versions before 3.1.4, use jquery-1.3.2.min.js !</script>
<script>
$.noConflict();
jQuery(document).ready(function($) {
var fieldDate1 = $("#Date1").parent().parent().find("input");
var fieldDate2 = $("#Date2").parent().parent().find("input");
var fieldDiff = $("#Diff").parent().parent().find("input");
function OCDateToJDate(OCDate){
//this function takes a date item in OpenClinica-notation
//and returns a date object
//The names of the months are compared with the array in the Calendar utility
//located in /includes/new_cal/lang
var dateParts = OCDate.split("-");
var JDate = new Date(1900,1,1);
JDate.setFullYear(dateParts[2]);
JDate.setMonth(Calendar._SMN.indexOf(dateParts[1]));
JDate.setDate(dateParts[0]);
return JDate;
}
function DiffInDays(OCDate1, OCDate2){
//calculate how many milliseconds are in a day
var msecPerDay = 1000 * 60 * 60 * 24;
//calculate millisecs for both dates
var milliSec1=OCDateToJDate(OCDate1).getTime();
var milliSec2=OCDateToJDate(OCDate2).getTime();
//take the difference
var interval =milliSec2 - milliSec1;
//calculate the days
var days = Math.round(interval / msecPerDay );
if (isNaN(days)){
return 0;
}
else{
return days;
}
}
function calcDiff(){
//calculate the difference
var calculatedDifference = DiffInDays(fieldDate1.val(), fieldDate2.val());
//only write the difference if it's not already there
if (fieldDiff.val() != calculatedDifference){
fieldDiff.val(calculatedDifference);
fieldDiff.change();
}
};
fieldDate1.blur(function(){
calcDiff();
});
fieldDate2.blur(function(){
calcDiff();
});
fieldDiff.blur(function(){
calcDiff();
})
fieldDiff.focus(function(){
calcDiff();
})
$("#srl").focus(function(){
calcDiff();
});
$("#srh").focus(function(){
calcDiff();
});
})
</script>
and then how it works
Central in this bit of javascript is the function OCDateToJDate which takes an OpenClinica-date and converts it into a javascript Date-object. This is done by splitting the date into three parts at the dash: dateParts = OCDate.split("-");. The year and the days can be used immediately, but the month is given as three letters. And these can differ, depending on your i18n-settings. For example if you're using OpenClinica with Dutch i18n-files (and you can: I'm serious), the name of the month would not be Oct but okt, like this:
fig. 3: Dutch interface
(You can read more about i18n here.)
To get the correct number of the month, we look at an array called Calendar._SMN, which is included in our page,
because we have a calendar-utility. This is defined in OpenClinica/includes/new_cal/lang/calendar-xx.js, where
xx stands for the language code.
The rest of the script speaks more or less for itself, except maybe the part where the calculation is made. This will happen when Date1 or Date2 loses focus, or when one of the two Save-buttons, or the item with the difference gets the focus. This may seem a bit overdone, but comes from the fact that when we use the calendar-utility, the item does not get the focus! Normally the blur-event would suffice, but in this case there will be no focus and hence no blur. Unless of course the date is typed-in manually. That's why fieldDiff.focus is added and you may want to add (even more) extra information in the RIGHT_ITEM_TEXT like click to calculate the difference.
You may look at the script and wonder where the var JDate = new Date(1900,1,1); comes from: can't we just take
var JDate = new Date();? Well, we can not, because on some days this may mess up our calculation. Suppose that today is 31-Mar-2016.
This is stored in JDate. If we now try to use this to set JDate to 02-Sep-1962 then this is done in three steps:
first the year, then the month and then the day. So ideally JDate would be:
31-Mar-2016
31-Mar-1962
31-Sep-1962
02-Sep-1962
But in the month-step this goes wrong, because 31-Sep will be changed automatically to 01-Oct and JDate will end up as 02-Oct-1962.
This will not happen when we choose 01-Jan-1900 as starting date. Or any other date, as long as the month has 31 days.
Other how-to-pages can be found here.
this page was last reviewed March 2016