Adding Two Hours in DataWeave: Mule 4
In this tutorial, follow an example case of a JSON array to learn the steps of implementing two hour values in DataWeave.
Join the DZone community and get the full member experience.
Join For FreeCase:
You are given a JSON array that will have all the employee's work details as an element.
Example input in JSON :
[
{
"Id": "870",
"ProjectId": "705032",
"ProjectName": "Out-Of-Office",
"Hours": "04:00"
},
{
"Id": "870",
"ProjectId": "17427",
"ProjectName": "ABC",
"Hours": "08:00"
},
{
"Id": "870",
"ProjectId": "78185",
"ProjectName": "XYZ",
"Hours": "06:00"
}
]
Expected output in JSON:
[
{
"TotalHours": "18.00"
}
]
Implementation:
Let's analyze the input first.
- The key is
Hours
and value is in the type of string. - We need to convert the string to Time, add those Time values, and return as Total Hour.
As we don't have any direct method to Add 2 Hours. We will be using our own Type HoursMinutes.
type HoursMinutes = {hour:Number, minute: Number}
This HoursMinutes
will have 2 elements as the hour and minute.
Steps:
- Split based on a delimiter (in this case ":").
- Convert the split strings to numbers.
- Add minutes to minutes and hours to hours.
- Concatenate both Hours and Minutes with a required delimiter.
Look at the following DataWeave script:
%dw 2.0
output application/json
//Creating custom type
type HoursMinutes = {hour:Number, minute: Number}
//Function to convert String input to Custom type object
fun toHours(n: String): HoursMinutes = do {
var split = n as String splitBy ":" //Change this if you have different delimiter
var hours = split[0] as Number
var fromMin = floor(split[1] as Number / 60) // This is to make hours from minutes if minutes are greater than 60
---
//output will be the custom type with hours and minute values
{hour:floor(hours) + fromMin, minute:split[1] as Number mod 60}
}
//Function to add 2 Custom Type Objects
fun add(hour1:HoursMinutes, hour2: HoursMinutes): HoursMinutes = do {
var fromMin = floor((hour1.minute + hour2.minute) / 60)
---
{hour: hour1.hour + hour2.hour + fromMin, minute: (hour1.minute + hour2.minute) mod 60}
}
//Function to form output in proper format (modify this if you want output differently)
fun toNumber(h: HoursMinutes) = (h.hour as String ++"."++ if (h.minute as String == "0") "00" else h.minute as String )
---
[
{
//using reduce function with accumulator/lambda function
"TotalHours": toNumber(payload reduce ((item, accumulator:HoursMinutes = {hour:0, minute:0}) -> accumulator add toHours(item.Hours)))
}
]
This Script will work even if hours are more than 24 and minutes are more than 60. It will automatically convert minutes to proper hours and process.
Reference is taken from this example.
Opinions expressed by DZone contributors are their own.
Comments