IBM Support

Timestamp Math with the Timestamp Utility Service

Technical Blog Post


Abstract

Timestamp Math with the Timestamp Utility Service

Body

Recently I worked on a PMR where the client was looking to do some logic based decisions in BPML based on how old certain files are.  This particular client also had a need to generate some timestamps with dates from the future.  It's easy enough to get the current time in different formats out of the Timestamp Utility Service, but was a bit trickier than I expected to get some of the math working.
 
The Timestamp Utility Service parameters are documented but some solid examples would be even more useful, so let's see what we can come up with.
 
First of all, the Timestamp Utility Service uses the SimpleDateFormat java class to generate its time and date stamps.  IBM will typically only publish javadocs for IBM specific implementations, so we can just follow the Oracle/Sun docs here.  We can set our format by just selecting the format characters we want in our string.  Here's an example of a configured timestamp service which yields a nicely formatted string of the current time to be used, say, in a notification email:
 
    <operation name="Timestamp Utility">
      <participant name="TimestampUtilService"/>
      <output message="TimestampUtilServiceTypeInputMessage">
        <assign to="." from="*"></assign>
        <assign to="action">current_time</assign>
        <assign to="format">MM-dd-yyyy G  hh:mm:ss.SSS a z</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
This results in the following output to ProcessData:
 
    <ProcessData>
      <currentTimeMillis>1398712700274</currentTimeMillis>
      <time>04-28-2014 AD  03:18:20.274 PM EDT</time>
    </ProcessData>
 
But, what about when you want to start adding timestamps, or getting a difference between them?  Well, let's consider what that means.  Each timestamp that the service creates or parses can be formatted as a number of milliseconds.  This number represents the amount of time that has passed since the Unix Epoch, January 1, 1970 (affectionately known as the Beginning of Time).  So adding today's date to tomorrow's date would give us summed date some 44 years out.  It makes much more sense to add or subtract a small time interval to a current date, though, so we can get recent or near future timestamps for filenames or decision-making.  It would also make sense to subtract an earlier timestamp from a later timestamp to find out the amount of time that has passed.
 
Using some additional parameters in the Timestamp Utility Service makes this much easier to do.
 
First, let's test out what I said about the Unix Epoch.  Let's see what time it is at 1 millisecond.  Here, I've removed the current_time action and I'm simply formatting 1 millisecond according to my SimpleDateFormat string
 
    <operation name="Timestamp Utility">
      <participant name="TimestampUtilService"/>
      <output message="TimestampUtilServiceTypeInputMessage">
        <assign to="." from="*"></assign>
        <assign to="action">format</assign>
        <assign to="baseTime">1</assign>
        <assign to="format">MM-dd-yyyy G  hh:mm:ss.SSS a z</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
This provides the following output in Process Data, which certainly is the Unix Epoch time-shifted for Eastern Time Zone:
 
    <ProcessData>
      <formattedTime>12-31-1969 AD  07:00:00.001 PM EST</formattedTime>
      <formatedTime>12-31-1969 AD  07:00:00.001 PM EST</formatedTime>
    </ProcessData>
 
So, now we can start adding on to our times.  Let's say I need to create a timestamp with a date exactly 10 hours and 30 minutes after I have begun processing a file.  This timestamp will be used as part of a filename and indicates the agreed upon time that the partner must receive the file by.  This is a purely arbitrary requirement (like a lot of requirements).  How can this be accomplished?  I'd start by getting the current time, and then adding the interval to it.  You must select units for the interval, so we will select "minutes" as this is the largest unit in which we can still pass an integer for our requirement (630 minutes).  You can also use the handy keyword, "now", to indicate that your baseTime should be figured using the current timestamp on the server.
 
So, my service now looks like this:
 
   <operation name="Timestamp Utility">
      <participant name="TimestampUtilService"/>
      <output message="TimestampUtilServiceTypeInputMessage">
        <assign to="." from="*"></assign>
        <assign to="action">add</assign>
        <assign to="baseTime">now</assign>
        <assign to="format">yyyyMMddhhmmssSSS</assign>
        <assign to="offsetTime">630</assign>
        <assign to="scale">min</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
 
It is more helpful, here, to look at the Status Report at the Timestamp Utility Service to see how it is being figured.  Note that I have selected a timestamp format string which can help keep filenames in order based on timestamp:
 
    Action: add
    
    The base time is 20140428043009178.
    The offset time is 630.
    The format string is yyyyMMddhhmmssSSS.
    The scale is set to min.
    The base time stamp after adding offset time is 20140429030009178.
 
Finally, let's take a look at subtracting two dates from one another to see how much time has passed between two timestamps.  Like addition, subtraction also uses the offsetTime parameter with the scale parameter to declare the number of units to be subtracted from the base time.  Simply changing the action from "add" to "diff" above yields the following:
 
    Action: diff
    
    The base time is 20140428043204790.
    The offset time is 630.
    The format string is yyyyMMddhhmmssSSS.
    The scale is set to min.
    The base time stamp after subtracting offset time is 20140428060204790.
   
But, how do we subtract one date from another?  You can't define an offsetTime with a particular format.  It's just an integer with a scale parameter.  What we CAN do is use a second timestamp service and some trickery to get the time in milliseconds since the beginning of time, by adding zero to our timestamp.  We then use the milliseconds returned as the offsetTime in the next Timestamp Utility Service.  This works pretty well if you leave everything in milliseconds until it comes down to your final conversion time.  Then, if you need a date/timestamp, just run the milliseconds through the Timestamp Utility Service in format mode, or do the conversion yourself as in this example:
 
 
Have you got any tips for using Timestamp Utility Service?  If so, leave them in the comments below.  I'd love to hear them.

[{"Business Unit":{"code":"BU059","label":"IBM Software w\/o TPS"},"Product":{"code":"SS3JSW","label":"IBM Sterling B2B Integrator"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB59","label":"Sustainability Software"}}]

UID

ibm11122153