Custom Script - Problem implementing code that calculates

Hello, I’ve gotten stuck one again :sweat_smile:

In my previous topic, I was able to successfully test a Custom Script that calculates the difference between two times in hours, minutes, and seconds and returns a string.

Example: 0h:5m:23s

However, now that I’m implementing the script with Recorder Variables, it’s throwing the Exception Handling and I haven’t been able to figure out why.

Could you help me find out why this isn’t working?

=============== Details =================

The Custom Script function, calcRuntime(), has one DateTime input:

@CustomScriptAction(
     input = ['bot_start_time'],
     output = 'runtime_str'    
)

’bot_start_time’ is calculated at the beginning of the bot with this Custom Action Script:

@CustomScriptAction(
     output = 'bot_start_time'
)

def getNow() {
     RDateTime.now()
}

Later on, the calcRuntime() function is called:

                @CustomScriptAction(
                	input = ['bot_start_time'],
                	output = 'runtime_str'    
                )
                
                
                def calcRuntime() {
					// Returns a string containing the number of hours, minutes, and seconds between the two DateTimes
					// Example: "<hours>h:<minutes>m:<seconds>s" 
					//          "0h:3m:45s"
					
					// Get the current time's hours, minutes, and seconds
					def now = RDateTime.now();
					def h_now = now.getHour();
					def m_now = now.getMinute();
					def s_now = now.getSecond();
					
					// Get the start time's hours, minutes, and second
					def h_start = bot_start_time.getHour();
					def m_start = bot_start_time.getMinute();
					def s_start = bot_start_time.getSecond();
					
					// Calculate the differences between the hours, minutes, and seconds
					def new_runtime_h = (h_now - h_start);
					def new_runtime_m = (m_now - m_start);
					def new_runtime_s = (s_now - s_start);
					
					// Handle negative minutes
					if (new_runtime_m < 0) {
						new_runtime_h -= 1;
						new_runtime_m = 60 - (new_runtime_m * -1);
					}
					
					// Handle negative seconds
					if (new_runtime_s < 0) {
						new_runtime_m -= 1;
						new_runtime_s = 60 - (new_runtime_s * -1);
					}
					
					// Return a new string containing the new runtime
					runtime_str = (new_runtime_h + 'h:' + new_runtime_m + 'm:' + new_runtime_s + 's');
				}

Thank you for your help!

Hi @mneff14,

Is it possible to execute your Custom Action outside of Exception Handling and show the error message with stack trace that occurs? Does it work in Actions Flow itself?
By the way, I didn’t see any imports in your Custom Action, looks like import java.time.* should be added. Import section should be before CustomScriptAction definition, see this sample.

Okay, so I separated the two Custom Action Scripts into their own recording, created the variables, added the import java.time.*, and played the recording, and this is the error I got while it ran the “Get Run Time” script:

image

Thank you, @mneff14. Please check variable name in “Recorder Variables” tab and in your script, they differ:

  • run_time_str - in Variables list.
  • runtime_str - in Custom Script

Oh, right! Thank you!

Okay, I changed the variable names, and I’ve still got another error with casting a String to RDateTime. Which RDateTime variable is it referencing?


image

Hello @mneff14,

You need to return RDataType result. Correct your last row with result output as below:
runtime_str = RString.of(new_runtime_h + 'h:' + new_runtime_m + 'm:' + new_runtime_s + 's')
Here is the documentation: Recorder Data Types.

That got it to run! Thank you very much!!!

1 Like

Welcome! :slightly_smiling_face:

Here’s the fully functional code, now altered to calculate the run time, even if the dates cross over a leap year!

                import java.time.*
                
                
                // Map Recorder Variables
                @CustomScriptAction(
                	input = ['bot_start_time'],
                	output = 'runtime_str'    
                )
                
                
                def calcRuntime() {
					// Returns a string containing the number of hours, minutes, and seconds between the two DateTimes
					// Example: "<days>d:<hours>h:<minutes>m:<seconds>s" 
					//          "0d:2h:3m:45s"
					//
					// Side Note: This function will correctly calculate the runtime even if the bot ran into the next year from a leap year!
					
					
					// Get the current time's hours, minutes, and seconds
					def now = RDateTime.now();
					def d_now = now.getDayOfYear();
					def h_now = now.getHour();
					def m_now = now.getMinute();
					def s_now = now.getSecond();
					
					// Get the start time's hours, minutes, and second
					def d_start = bot_start_time.getDayOfYear();
					def h_start = bot_start_time.getHour();
					def m_start = bot_start_time.getMinute();
					def s_start = bot_start_time.getSecond();
					
					// Calculate the differences between the hours, minutes, and seconds
					def new_runtime_d = (d_now - d_start);
					def new_runtime_h = (h_now - h_start);
					def new_runtime_m = (m_now - m_start);
					def new_runtime_s = (s_now - s_start);
					
					// Handle negative days
					if (new_runtime_d < 0) {
						new_runtime_d *= -1
						// Handle Leap years
						if (new_runtime_d > 364) {
							new_runtime_d = 366 - new_runtime_d;
						} else {
							new_runtime_d = 365 - new_runtime_d;
						}
					}					
					
					// Handle negative hours
					if (new_runtime_h < 0) {
						new_runtime_d -= 1;
						new_runtime_h = 24 - (new_runtime_h * -1);
					}					
					
					// Handle negative minutes
					if (new_runtime_m < 0) {
						new_runtime_h -= 1;
						new_runtime_m = 60 - (new_runtime_m * -1);
					}
					
					// Handle negative seconds
					if (new_runtime_s < 0) {
						new_runtime_m -= 1;
						new_runtime_s = 60 - (new_runtime_s * -1);
					}
					
					// Return a new string containing the new runtime
					runtime_str = RString.of(new_runtime_d + 'd:' + new_runtime_h + 'h:' + new_runtime_m + 'm:' + new_runtime_s + 's');
				}