Home > OS >  Round back to quarter-hour in Mulesoft Dataweave
Round back to quarter-hour in Mulesoft Dataweave

Time:11-19

I have a Mule Server 4.3.0 EE application, and in it I want to round a DateTime to its most recent quarter-hour, with the result also being a DateTime. Some examples:

  • if the input is 9:18:32 AM, then the output is 9:15:00 AM the same day
  • if the input is 9:33:33 AM, then the output is 9:30:00 AM the same day
  • if the input is 9:59:58 AM, then the output is 9:45:00 AM the same day
  • if the input is 10:00:00 AM, then the output is 10:00:00 AM the same day

In this application, the input will always be in New York time, with DST in effect or not depending on the time of year.

Here's what I've come up with so far. Keep the date and hour, truncate the minutes to the nearest 15, set the seconds to zero, and keep the time zone. (There's a special case for '00' minutes because it won't convert if the minutes are a single '0'.)

I know newer Mule versions have the Dates package which would make this much more elegant, but upgrading isn't currently an option for me. Is this about as good as the code can be for those requirements, or is there a better way to do this without upgrading Mule? Thank you.

%dw 2.0
import * from dw::core::Strings
output application/json
fun roundBack(inputTime: DateTime): DateTime =
(inputTime[0 to 13]   
    (if (inputTime.minutes < 15) '00' else (inputTime.minutes - mod(inputTime.minutes, 15) as String))   
    ':00'   
    inputTime[-6 to -1]
) as DateTime

CodePudding user response:

I believe that the logic is good but the implementation is fragile because it depends on auto coercions (DateTime to Strings when using the range selector []). It is better for me to be explicit in the conversions to avoid issues caused by unexpected defaults formats and warnings in the editor:

%dw 2.0
import * from dw::core::Strings
output application/json
fun roundBack(inputTime: DateTime): DateTime =
    (
        inputTime as String {format: "yyyy-MM-dd HH:"} 
           (if (inputTime.minutes < 15) 
                '00' 
            else (inputTime.minutes - mod(inputTime.minutes, 15)) as String
        )
          ':00' 
           inputTime as String {format: "xxx"}
    ) as DateTime {format: "yyyy-MM-dd HH:mm:ssxxx"} 
---
roundBack(|2020-10-01T23:57:59-04:00|)

Output: "2020-10-01 23:45:00-04:00"

  • Related