Skip to main content
Known Participant
October 25, 2022
Answered

I need help with a form that calculates hours worked.

  • October 25, 2022
  • 3 replies
  • 14355 views

Hello

I have a form that calucates hour worked. There are two time-in and time-out sections that are added together to get the total hours worked. Everything works fine if the time-in and time-out values are in the same 12-hour period. If a worker clocks in at 8:00am and clocks out at 5:13pm the total hours worked is 9:13. All is well in the world.

 

Here is the problem. If a worker clocks in at say 8:00pm and clocks out at 3:00am the next morning, I get a value of -17:00. Something isn't calcuating correctly when we go from pm to am.

The code I have to calculate time in and time out is:

/*
document level functions:
Scand
AdjustMidnight
DateTime2Min
*/

// get the input fields;
var cStartDate = util.printd("dd-mmm-yyyy", new Date());
var cStartTime = this.getField("StartTime").valueAsString;
var cStartDateFormat = "dd-mmm-yyyy";
var cStartTimeFormat = "h:MM tt";
cStartTime = AdjustMidnight(cStartTime);
var cEndDate = util.printd("dd-mmm-yyyy", new Date());
var cEndTime = this.getField("EndTime").valueAsString;
var cEndDateFormat = "dd-mmm-yyyy";
var cEndTimeFormat = "h:MM tt";
cEndTime = AdjustMidnight(cEndTime);
// compute elapsed time in minutes;
event.value = 0;
// compute elapsed time ony if we have data;
if(cStartDate != "" && cStartTime != "" && cEndDate != "" && cEndTime!= "")
{
	event.value = DateTime2Min(cEndDateFormat + " " + cEndTimeFormat, cEndDate + " " + cEndTime) - DateTime2Min(cStartDateFormat + " " + cStartTimeFormat, cStartDate + " " + cStartTime);
} // end date objects not null;
// final format is done through the custom format option;


Any help would be greatly appreciated. I have attached a copy of the form if anyone wants to see exactly how I have it set up. Make sure you add am or pm after the time value
ex: "8:13am" then press the tab button.

Thank you.

Correct answer Thom Parker

No errors in the console. The time does calculate correctly if I add times to both in-out rows. A single row still outputs random numbers in bottom total field. I did try to write a conditional statement to print a zero if the first box was empty to elimate the random numbers. I tried it both with a ternary and an if-else statement. No affect, of course, because I'm sure my syntax is off.

var strTime1 = this.getField("HoursWorked2").value; 
var strTime2 = this.getField("hoursWorked").value; 

var aTime1 = strTime1.split(":");
var aTime2 = strTime2.split(":");

var nHours = Number(aTime1[0]) + Number(aTime2[0]);
var nMinutes = Number(aTime1[1]) + Number(aTime2[1]);

if(aTime2 == "") {
    event.value = util.printf("0")
} else {
    nHours += Math.floor(nMinutes/60);
    nMinutes = nMinutes%60;
    event.value = util.printf("%d:%d",nHours,nMinutes)
}





So the way to do this is to write the code so it gives you sensible results.

If no (invalid) time is entered in either slot, then a blank result. 

If only one time is entered, then just show that value. 

 

The easy solution is to use a regular expression to detect and set values that will flow seemlessly throught the code. 

 

Like this:

 

var strTime1 = this.getField("HoursWorked2").value; 
var strTime2 = this.getField("hoursWorked").value; 
var aTime1 = [0,0], aTime2 = [0,0];
var rgTimeFormat = /^\d+\:\d{2}$/;

if(rgTimeFormat.test(strTime1))
    aTime1 = strTime1.split(":");

if(rgTimeFormat.test(strTime2))
    aTime2 = strTime1.split(":");

var nHours = Number(aTime1[0]) + Number(aTime2[0]);
var nMinutes = Number(aTime1[1]) + Number(aTime2[1]);

nHours += Math.floor(nMinutes/60);
nMinutes = nMinutes%60;
if(!nHours && !nMinutes)
    event.value = "";
else
    event.value = util.printf("%d:%02d",nHours,nMinutes)

 

3 replies

JR Boulay
Community Expert
August 28, 2025

[MOVED TO THE ACROBAT PRO DISCUSSIONS]

Acrobate du PDF, InDesigner et Photoshopographe
New Participant
August 20, 2025

 

Hi @kryan74,

The issue you’re facing is quite common when calculating hours that cross over midnight. The negative value happens because the end time (3:00am) is technically earlier than the start time (8:00pm) if you don’t account for the date change.

One way to fix this is to add a condition: if the end time is less than the start time, then treat the end time as being on the next day. For example:

 

 
if (cEndTime < cStartTime) { // add 24 hours in minutes event.value += 24 * 60; }
if (cEndTime < cStartTime) {
// add 24 hours in minutes
event.value += 24 * 60;
}
 

This ensures the calculation properly handles shifts that cross midnight.

I’ve worked with similar scenarios when building tools for tracking work hours. In fact, if you want a quick way to test these calculations without editing the script every time, you could try this free online calculator I use: https://ecalculadoradehoras.com/ – it handles overnight shifts and overtime automatically.

Hope this helps!

Thom Parker
Community Expert
October 25, 2022

You're calculations are a bit overly complex.  The addition of a date is necessary to anchor the calculation to a single day, but no midnight adjustment is needed.  And the formatting is simple to do using the date object functions. 

 

Here is a simpler script that doesn't require the extra functions. 

Notice that this code uses a "bSameDay" variable. If true, then a negative difference in time is left negative, but if false, it is subtracted from 24 hours.  Also notice that the date used is the zero time for the date object, i.e. midnight Dec 31, 1969 in Grenich England. The where and when computer time began.  This is totally arbitrary. It's only necessary the times are on the same day.  

It is assumed the time formatting and numbers are not in error.  Extra code would be necessary if you want time format checking. Do not format the output field. 

 

// Get Start and end time strings
var strTime1 = this.getField("StartTime").valueAsString;
var strTime2 = this.getField("EndTime").valueAsString;;

// add code here to check for valid time values, before proceeding.

// Calculation parameters
var bSameDay = false;
var strInFormat = "h:MM tt";
var strOut = null;
var bNeg = false;
var strFullFormat = "dd-mm-yyyy " + strInFormat;

// get difference in times in miliseconds. 	
var nDiffMs = util.scand(strFullFormat, "31-12-1969 " + strTime2).getTime() - util.scand(strFullFormat, "31-12-1969 " + strTime2).getTime();
if(nDiffMs < 0){
	if(bSameDay){
		bNeg = true;
		nDiffMs = Math.abs(nDiffMs);
	}else // Shift 24 hours
		nDiffMs += 86400000;
}

// format time differnce. 	
var dtDiff = new Date(nDiffMs);
strOut = util.printf("%02d:%02d", dtDiff.getUTCHours(), dtDiff.getUTCMinutes());
if(bNeg) strOut = "-" + strOut;
event.value = strOut;

 

 

 

  

 

 

 

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often
kryan74Author
Known Participant
October 26, 2022

Thomas

I really appreciate your repsonse and simplified code. I apologize for my novice understanding of the solution. Unfortunatly that didn't work - most likely because I didn't implement it correctly in my form. I replaced the script in the "hours" column with your code (both output boxes) and removed the formatting like you suggested. Both boxes now show "23:59" and nothing caluclates.

Can you help me implement your script with my particular form?

Thom Parker
Community Expert
October 26, 2022

My bad, only time2 is being used in the calculation. So it's rounding out to -1 minute

Here's the corrected code. 

// Get Start and end time strings
var strTime1 = this.getField("StartTime").valueAsString;
var strTime2 = this.getField("EndTime").valueAsString;;

// add code here to check for valid time values, before proceeding.
if(strTime1 != "" || strTime2 != ""){
	// Set Calculation parameters
	var bSameDay = false;
	var strInFormat = "h:MM tt";
	var strOut = null;
	var bNeg = false;
	var strFullFormat = "dd-mm-yyyy " + strInFormat;

	// get difference in times in miliseconds. 	
	var nDiffMs = util.scand(strFullFormat, "31-12-1969 " + strTime2).getTime() - util.scand(strFullFormat, "31-12-1969 " + strTime1).getTime();
	if(nDiffMs < 0){
		if(bSameDay){
			bNeg = true;
			nDiffMs = Math.abs(nDiffMs);
		}else // Shift 24 hours
			nDiffMs += 86400000;
	}

	// format time differnce. 	
	var dtDiff = new Date(nDiffMs + 10);
	strOut = util.printf("%02d:%02d", dtDiff.getUTCHours(), dtDiff.getUTCMinutes());
	if(bNeg) strOut = "-" + strOut;
	event.value = strOut;
}else  
	event.value = "";

 

I've also added protection for blank inputs.   To do this right, code should also be added to test for correctly formatted input. 

 

 

Thom Parker - Software Developer at PDFScriptingUse the Acrobat JavaScript Reference early and often