IBM Support

Maximo Scripting: Date Dizziness - Part III

Technical Blog Post


Abstract

Maximo Scripting: Date Dizziness - Part III

Body

Introduction

In Part II of the series of articles calculating dates, we learned to use the Java Calendar and Date classes and methods. The question is: What is the equivalent in JavaScript? This article picks up where Part II left off and implements a JavaScript-based script to calculate dates.

JavaScript-based date calculation

The scenario is exactly the same as Part II, so I will not go over the set up details again. Please review Part II if you need to understand how scripting is leveraged to calculate dates. To summarize: I created an escalation that runs every minute, executing an action that checks Service Request (SR) records. If a record meets certain criteria, then the script associated with the action calculates target contact date and target start date and applies them back to the SR record.

In this article, I investigate JavaScript capabilities in dealing with dates. My primary source is the Mozilla Developer Network website and documentation for JavaScript. But before I dive into the code, let me summarize how I put the necessary configurations for this scenario into place.

I followed these steps:

  1. Using Automation Scripts application, define a new action launchpoint and author the JavaScript-based script. Under the covers, this activity will generate an action.
  2. Using the Escalation application, update the SRDDESC escalation to point to the new action.

New action launch point, action and script

All three entities (action launchpoint, action and script) are named SRDDACTIONJS. I take care to change the script language to ‘javascript’. I associate the same input and output variables as I did with the action launchpoint from Part II: input variables – reportdate; output variables – targetcontactdate, targetstartdate.

The JavaScript code is shown below.

function ISODateString (d)

{

  function pad(n){return n<10 ? '0'+n : n}

  return d.getUTCFullYear()+'-' 

       + pad(d.getUTCMonth()+1)+'-' 

       + pad(d.getUTCDate())+'T' 

       + pad(d.getUTCHours())+':' 

       + pad(d.getUTCMinutes())+':' 

       + pad(d.getUTCSeconds())

}

 

println ('SRDDACTIONJS - script execution started');

var currentTime = new Date(reportdate.getTime());

currentTime.setDate(currentTime.getDate() + 1) ;

targetcontactdate = ISODateString(currentTime);

currentTime.setDate (currentTime.getDate() + 1);

targetstartdate = ISODateString(currentTime);

println ('SRDDACTIONJS - script execution complete');

The basic logic in the script is the same as before: based on reportdate, calculate targetcontactdate and targetstartdate. Targetcontactdate is calculated to be 1 day from reportdate; while targetstartdate is calculated to be 2 days from reportdate. I identified the JavaScript Date object as the primary object I would use to calculate the required dates. The trick, though, is to determine how to leverage the Date object and its methods.

As I coded this script, I ran into a number of problems. Here are the problems and how I overcame them:

  1. The input variable reportdate is a Java-based Date object. It cannot be used as is with the JavaScript Date object. A JavaScript Date object can be initialized a number of ways. Given I have an input variable, reportdate, that already provides a date and time value, I chose to initialize the JavaScript Date object as a value representing time in milliseconds. I utilize the Java Date object’s getTime() method to obtain the ‘reportdate’ time value in milliseconds and construct my JavaScript Date object from that millisecond value.
  2. There are JavaScript Date methods to get and set date / time information. However, when I needed to set the output variables of the script, I discovered I could not simply return a JavaScript Date object. I had to determine a suitable way of returning the calculated date that Maximo would accept and set into the attributes of the target SR record.
  3. Returning the value from a JavaScript Date.toDateString() or Date.toLocaleDateString() resulted in Maximo throwing this error: “BMXAA4144E - The date/time format is not valid. Make sure the date/time is specified in a valid format supported by the current locale setting”.
  4. Returning the value from a JavaScript Date.getTime() resulted in Maximo throwing this error: “BMXAA7816E - Operation setValue(double value) is not supported on data type DATETIME. Report the error to your system administrator.”

In researching this, I identified the fact Maximo expects its date value to adhere to a certain format. One of the acceptable formats is a date time value represented in the ISO 8601 format. I found that while JavaScript supports a variety of date operations, it does not offer an easy-to-use mechanism to format a date. After searching the web, I discovered that other developers had experienced the same problem and come up with their own versions of classes and methods to enable formatting of a date string. Interestingly, I found an open source library, Datejs, that seeks to address the shortcomings of the basic JavaScript date processing capabilities. I concluded if I could build an ISO 8601 compliant date-time string, I could set that value back into the output variables of the script.

A little bit more research and I noticed that with JavaScript 1.8, a method toISOString() had been added to the Date object. However, JDK 6 and consequently, Maximo 7.5 ships with Mozilla JavaScript 1.6 only. I can’t take advantage of the new method either.

I authored a simple function inside my script that accepts JavaScript Date object as parameter and constructs an ISO 8601 date-time string. This is the ISODateString() function at the top of the script. The ISO 8601 format is usually expressed in the form:

<full year>-<month>-<day>T<hours>:<minutes>:<seconds>

or as:

YYYY-MM-DDThh:mm:ss

I used the available methods of the JavaScript Date object to retrieve the information I needed in the right order. Once I had constructed the ISO 8601 compliant string representation of the calculated date, I simply set my output variables from the value returned by the ISODateString() function.

In the function, the call to Date.getUTCMonth() is followed by a ‘+1’ since that method returns an integer between 0 and 11 what we need is an integer between 1 and 12.

By including a simple println() statement within the body of the script, one can view the output of the ISODateString() function. It is similar to:

2011-12-26T04:37:33

The pad() function inside the ISODateString() function is used to place a zero to the left of the number (month, date, hours, minutes or seconds) if that number is below 10 to ensure the final string is ISO 8601 compliant.

Testing the new script

With these code changes, the script begins to work as expected populating the SR record’s Target Contact Date and Target Start Date. To test follow these steps (the escalation definition was set up in Part II):

  1. In the Escalations application, access the SRDDESC escalation definition.
  2. De-activate the escalation, if needed, and then delete the SRDDACTIONJAVA action.
  3. Associate the new action SRDDACTIONJS with the escalation. Save and activate.

Summary

Date calculations can be performed using JavaScript’s Date object. The one drawback is the difficulty in formatting date / time strings which need to be overcome by writing simple functions as I did for the Service Request scenario. I welcome any feedback from the community: Do you know a better way to work with and format dates in JavaScript? Let me know.

Useful Links

Date Dizziness – Part I

Date Dizziness – Part II

[{"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SSLKT6","label":"IBM Maximo Asset Management"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB59","label":"Sustainability Software"}}]

UID

ibm11134669