How to handle abbreviated year pattern (yy) in Mule 4 - mule

Input:
{
"date": "01-JAN-70"
}
Expected Output:
{
"date": "1970-01-01"
}
appreciate your input

This is an answer that doesn't use string operations, which is not a good practice for dates handling. The function replaceCentury() let's you replace the century of a date with another one.
%dw 2.0
output application/json
import * from dw::core::Dates
fun centuryFromYear(c)=floor( (c / 100)) * 100
// replaceCentury(): d is the input date, c is the century that you want the date to be in
fun replaceCentury(d: Date, c: Number)= date({year: d.year - centuryFromYear(d.year) + c, month: d.month, day: d.day})
var inputDate=payload.date as Date {format: "dd-MMM-yy"}
---
replaceCentury(inputDate, 1900)
Output:
"1970-01-01"

Try with this approach:
%dw 2.0
output application/json
var year = "19" ++ (payload.date splitBy "-")[2]
var fDate = ((payload.date splitBy "-")[0] ++ "-" ++ (payload.date splitBy "-")[1] ++ "-" ++ year)
---
fDate as Date {"format": "dd-MMM-yyyy"} as String {"format": "uuuu-MM-dd"}

Related

How to Group consecutive dates together which are separated by hour in Dataweave?

I have the following input data and I am trying to group consecutive DateTime together that increments by hr. version used: Dataweave 2.3, Mule 4.3
Input data.
["2020-03-03T06:00:00", "2020-03-03T07:00:00", "2020-03-03T08:00:00",
"2020-03-03T09:00:00", "2020-03-03T13:00:00", "2020-03-03T14:00:00",
"2020-03-03T15:00:00", "2020-03-04T06:00:00", "2020-03-04T07:00:00",
"2020-03-04T08:00:00", "2020-03-04T09:00:00"]
Business Logic:
From the above input some of the data are consecutive by hour. Index (0,1,2,3) and (4,5,6) and (7,8,9,10) are grouped by an hour. Aim is to merge these consecutive dates together and create object set as below with fromDate being lowest Date of the group and toDate being highest date of the group. Hope I am clear with requirement.
Expected Output.
[{"fromDate" : "2020-03-03T06:00:00", "toDate" : "2020-03-03T09:00:00" },
{"fromDate" : "2020-03-03T13:00:00", "toDate" : "2020-03-03T15:00:00" },
{"fromDate" : "2020-03-04T06:00:00", "toDate" : "2020-03-04T09:00:00" }]
I have tried map, groupby, reduce but couldn't figure this out. Please help.
Very interesting challenge. In order to do this I've implemented a function called clusterBy that groups consecutive elements that matches a given criteria. Once I have that I only needed to map the first and last of each cluster into the object. See the code below
%dw 2.0
fun clusterWhile<T>(elements: Array<T>, criteria: (source:T, target:T) -> Boolean) = do {
fun clusterLoop(elements, value, carrier, criteria) =
elements match {
case [] -> carrier
case [x ~ xs] ->
if(criteria(value, x)) do {
var updatedCarrier = carrier update {
case [-1] -> $ << x
}
---
clusterLoop(xs, x, updatedCarrier, criteria)
}
else
clusterLoop(xs, x, carrier << [x], criteria)
}
---
elements match {
case [] -> []
case [x ~ xs] -> clusterLoop(xs, x, [[x]], criteria)
}
}
---
payload
clusterWhile ((source, target) -> target as DateTime - source as DateTime == |PT1H|)
map ((item, index) -> {
fromDate: item[0],
toDate: item[-1]
})
This is what i came up with.
%dw 2.0
output application/csv headerLineNumber = 0 , header = true
//Below dtList results in Input Payload.
var dtList = flatten(payload.payload) map ($."updated-at" as DateTime as String {format: "u-LL-d'T'HH:00:00'Z'"}) orderBy ($) distinctBy ($)
var fromDt = dtList map ((item, index) -> if((item - |PT1H|) as String != (dtList[index-1])) item else "")
var toDt = fromDt map ((item, index) -> if(dtList[index] == item ) dtList[index-1] else "" ) filter ($ != "") orderBy ($)
---
fromDt filter ($ != "") map ((item, index) -> {fromDate: item} ++ {toDate: (toDt[index] + |PT1H|) })

How to Identify last element in an Array in Dataweave

i have a dataweave expression to create a custom String , but i do not want to append || to the last element of the input array . How can i achieve it ?
%dw 2.0
output application/json
var arr = ["ABC","XYZ"]
---
arr map((item,index) -> {
index: "custom ('" ++ item ++ "'); " ++ "||"
})
Would this help?
Script
%dw 2.0
output application/json
var arr = ["ABC","XYZ"]
---
arr map((item,index) -> {
index: if((index) < (sizeOf(arr)-1)) "custom ('" ++ item ++ "'); " ++ "||" else item
})
Output
[
{
"index": "custom ('ABC'); ||"
},
{
"index": "XYZ"
}
]
You could also try with the following:
%dw 2.0
output application/json
import * from dw::core::Arrays
var arr = ["ABC","XYZ"]
---
take(arr,(sizeOf(arr)-1)) map (
$ ++ "||" // do your manipulation to modify the custom entry
)
take is documented here
Out of curiosity, are you then taking this resulting array and joining it into a string? Your question seems to indicate the end goal of the function is returning a string. If you are, you can just map and then joinBy
%dw 2.0
output application/json
var arr = ["ABC","XYZ", "DKJL"]
---
arr map "custom($($));" joinBy " || "
Outputs
"custom(ABC); || custom(XYZ); || custom(DKJL);"
And if like in Salim's answer you shouldn't be wrapping the last value in custom, you could also take advantage of the default behavior of reduce:
%dw 2.0
output application/json
var arr = ["ABC","XYZ", "DKJL"]
---
arr[-1 to 0] reduce ("custom($($)); || " ++ $$)
Outputs
"custom(ABC); || custom(XYZ); || DKJL"

Why Date Field is not formatting in Data weave?

Hi i have a Date field which is coming as
{
"noteDate": "2013-12-18T00:00:00"
}
My Dataweave function is
%dw 2.0
output application/json
---
payload.noteDate as String {"format": "uuuu-MM-dd"}
//formattedDate: |2020-10-01T23:57:59| as String {format: "uuuu-MM-dd"}, // This is in Documentation
The output i am getting is
"2013-12-18T00:00:00"
Expected Output is
"2013-12-18"
How i can do it.
%dw 2.0
output application/json
---
payload.noteDate as Date
That is coming in as a string, not as a date. JSON has no concept of dates.
If you wanted to treat it as a DateTime and then apply a string format you could convert it first (shown below) but just casting it to a Date will do the same.
%dw 2.0
output application/json
---
(payload.noteDate as DateTime) as String { format: "uuuu-MM-dd" }

string to date conversion using dataweave

Input String: 201801
Output String format: 01.2018
I tried using following but it's not working, I also looked up for string to date convesrion/coercion table in "Type Coercion Table" https://docs.mulesoft.com/mule-user-guide/v/3.8/dataweave-types#type-coercion-table. I did not find something to help me with this.
as :date {format: "yyyyww"} as :string {format: "ww.yyyy"}
Appreciate if anyone has any ideas to share.
If you don't mind a bit of string hackery you could just move the various parts of the input string around:
%dw 1.0
%output application/json
%var inputDate = "201801"
---
{
outputDate: inputDate[4..5] ++ "." ++ inputDate[0..3]
}
The output of that is
{
"outputDate": "01.2018"
}
The above isn't null safe though, if there is a chance that the input date string is empty, or if it is shorter than 6 characters you will get a runtime error. You could work around that by checking the date in the DW, something like
outputDate: (inputDate[4..5] ++ "." ++ inputDate[0..3]) when inputDate != null and ( sizeOf inputDate ) == 6 otherwise null

How to parse yyyy-Mm-ddThh:mm:ss format in dataweave mule

I tried expression like below in mule dataweave but I am getting error.
pdate : "2017-06-22T12:45:55" as:datetime{format : "yyyy-Mm-dd'T'hh:mm:ss"} as :string{format: "MM/DD/yyyy"}
Can you please help on this if I missed anything to write.
try this:
%dw 1.0
%output application/json
---
{
pdate: "2017-06-22T12:45:55" as :localdatetime { format: "yyyy-MM-dd'T'HH:mm:ss" } as :string { format: "MM/dd/yyyy" }
}
changes compared to your version:
replace Mm with MM in first format string, thx #Dai
replace hh with HH in first format string
replace DD with 'dd' in second format string