Most Recent

Blog Post

Combining Date and Time Properties in Pega

Combining Date and Time Properties in Pega

While most of the business challenges at hand can be solved by choosing and configuring the appropriate rule type in PRPC, every now and then you might run into situations where the out-of-the-box solution just doesn´t cut it. During one of my more recent endeavors I discovered (red. or rather suffered) the consequences of having simple Time only properties defined instead of their Date & time counterpart.

In my everyday attempt to keep the data model as clean as possible I defined some timeline data structure as reusable class TimeRange for user selected times. The date already follows from the context; set at some earlier point in the process flow.

Analysis

Now, if you need to combine the two, meaning the contextual date with the times set by the user, you run into some trouble. You cannot simply @addToDate(DateTime, String, String, String, String) or semi-smartly concatenate the GMT date with the Time property, because it is in Local Time not GMT — as I mention in one of my previous articles on Data Types. The attempt to leverage the @toLOCAL(BigDecimal, String) function didn´t help much as it returns BigDecimal, so I wrote my own function that reverses the time shift getting you from local to GMT while maintaining Pega formatting.

Solution

I´ve written the following Java code as an exception to rule of having no custom code in PRPC. The parameters tab is shown as screenshot. The code itself is listed next. CombineDateAndLocalTime Parameters tab

String strResult = "";
String strTimeZone = "GMT";
DateTimeUtils dtu = ThreadContainer.get().getDateTimeUtils();
if (strTime.length() != 6) {
  strTime = "000000";
}
String strDateTime = strDate.substring(0, 8) + "T" + strTime + ".000 GMT";//Replace time in input dateTime with input time
Date dateCombined = dtu.parseDateTimeString(strDateTime);
PublicAPI tools = null;
PRThread thisThread = (PRThread)ThreadContainer.get();
if (thisThread != null) {
    tools = thisThread.getPublicAPI();
       strTimeZone = tools.findPage("pxRequestor").getString(".pyUseTimeZone");
}
String strLocal = PRDateFormat.format(null, strTimeZone, PRDateFormat.PEGARULES_INTERNAL_DATETIME, dateCombined);
String strGMT = PRDateFormat.format(null, "GMT", PRDateFormat.PEGARULES_INTERNAL_DATETIME, dateCombined);
Date dateLocal = dtu.parseDateTimeString(strLocal);
Date dateGMT = dtu.parseDateTimeString(strGMT);
//Calculate the difference in hours between Local timezone and GMT
double dblLocal = PRDateFormat.toDoubleAsDateTime(dateLocal);
double dblGMT = PRDateFormat.toDoubleAsDateTime(dateGMT);
double timeshift = -(dblLocal - dblGMT) * 24;//Shift from Local to GMT timezone in opposite direction (in seconds)
BigDecimal bd = new BigDecimal(timeshift);
bd = bd.setScale(0, RoundingMode.HALF_UP);
Double hrs = bd.doubleValue();
Integer hours = hrs.intValue();
//Now apply hours to compensate for the timeshift caused by Pega´s Time Control to GMT DateTimeString
strResult = dtu.addToDate(strGMT, "0", hours.toString(), "0", "0");//Note: addToDate takes strings and returns Pega ISO format

return strResult;

After compilation of your function library you can call this function inline in any Data Transform or Activity that is part of your application like:

@Library.CombineDateAndLocalTime(.SomeDate, .SomeTime)

Conclusion

In retrospect, this Java function can be programmed more elegantly. I decided to stay close to what´s already available in PRPC instead of some POJ degenerate Date/Calendar (but probably faster) computation to lower the risk of breaking things during a platform upgrade.

While it is perfectly fine to have PRPC store time properties in local time it did pose a challenge combining it with these GMT dates. One could side step this by always using Date & time properties, but such a workaround quickly leads to other drawbacks: What if you do not want to set the date at all? Also, you should not forget overriding the default control to Time only when adding this property to a Section. What if someone else switches the control back to Date input?

Beware that using a fake date when you effectively mean Time only (or any fake value for that matter) misleads and essentially burdens other programmers. When you define a property as Date & time you are in fact making a promise that all the rules referencing this new property will work as expected. I would encourage to use null or empty "" string where-ever appropriate. Don´t use epoch for dates. Just don´t set the property at all.

TIP: Always beware of the side-effects when testing pages and properties in Pega, since PRPC will create them on the Clipboard (heap) automatically when you forget to start with the "If exists" construct.

Feel free to share or improve the code above — no questions asked that is. Time flies! [Edgar] (8/4/2017 3:47:06 PM)

 

Twitter Feed

@edgarverburg

Bio

About Edgar

Edgar is a software engineer with experience in TIBCO Middleware and Pega Case Managemement. He holds a master's degree in Computer Science with a specialization in Data Visualization & Computer Graphics.

In his spare time Edgar reads SOS and Empire, mixes house music, blogs and writes film reviews or goes running.


Currently employed by SynTouch he is specifically looking for a PRPC project. Feel free to contact him for challenging assignments through LinkedIn.