Start week date based on week number and year - mule

i'm trying to convert year and week number to Date, specifically i need to get first day of week by week number. My idea was to convert my String to Date and then gat firstdayofweek but im struggling with converting to Date with error:
Cannot coerce String (201601) to LocalDateTime, caused by: Text '201601' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {WeekOfWeekBasedYear[WeekFields[SUNDAY,1]]=1, Year=2016},ISO of type java.time.format.Parsed
My DW script:
%dw 2.0
output application/json
var date = '201601'
---
'Date' : date as LocalDateTime {format: "yyyyww"}
and also tried
%dw 2.0
output application/json
var date = '201601'
import * from dw::core::Periods
import * from dw::core::Dates
---
atBeginningOfWeek((atBeginningOfWeek(date[0 to 3]++ "-01-01")) as Date + days(date [4 to -1] * 7))
But they are not working good, any ideas?

I think your second solution is the answer to what you are trying to achieve.
%dw 2.0
output application/json
var date = '201601'
import * from dw::core::Periods
import * from dw::core::Dates
---
atBeginningOfWeek(((date[0 to 3]) ++ "-01-01") as Date) + days (date[4 to -1]*7)
I believe this is giving correct answer to your requirement.

The first script will not work because 1) using a LocalDateTime but there is no time in the input and 2) a year and a week don't make a date. DataWeave only has features to convert strings containing year, month and day into a date so even using w in the pattern will not work. Incidentally this could be the one case where the pattern YYYY (week based year) would probably apply if there was a way to use a year-week in DataWeave. Usually using uppercase Y in a date pattern in Java or DataWeave is a bug, because it is not the correct pattern for dates.
The second script seems correct, but we should try to avoid using string manipulation for dates. That's a bad pattern if there are library functions in the language used. It is not possible to avoid all because there is no way to convert a week to a date but we can at least avoid the concatenations. I prefer to implement the logic in a function to facilitate reuse.
%dw 2.0
output application/json
import * from dw::core::Dates
import * from dw::core::Periods
var yearWeekString = "201601"
fun beginningOfWeekYear(year: Number, week: Number)=
atBeginningOfWeek(atBeginningOfWeek(date({ year: year, month: 1, day: 1})) + days(week * 7 ))
---
{
"201601": beginningOfWeekYear(yearWeekString[0 to 3] as Number, yearWeekString[4 to -1] as Number),
"202041": beginningOfWeekYear(2020, 41)
}
Output:
{
"201601": "2015-12-27",
"202041": "2020-10-04"
}
I validated the output using a week calendar.

Related

Compare Dates in Kotlin

How can i compare Dates in Kotlin?
I have the Date of an Event as a String (Format:dd/mm/yy) and I want to check if it is within the next 7 Days of the current Date.
The time in this case is not relevant or if needet I would use midnight.
Can someone please help me with this?
In my current code i got both Dates by this:
val date = document.data["Date"].toString() //Example: 22/08/22 (dd/MM/yy)
val today = SimpleDateFormat("dd/MM/yy").format(Date()).toString()
this is within a Android environment.
I can't get the date more specific because i am getting it from a Database.
Parse string into LocalDate using its parse method. There’s no out-of-the-box DateTimeFormatter for dd/mm/yy format, but you can trivially create one using DateTimeFormatter.ofPattern.
Get current date using LocalDate.now().
diff = ChronoUnit.DAYS.between(now, date1)

DataWeave 2.0 get time difference as a period

I have DataWeave code that looks like below:
%dw 2.0
output application/java
var timezone = (now() >> "Pacific/Auckland") as String {format: "XXX"}
var t1 = '08:00:00.000' ++ timezone
var t2 = '21:00:00.000' ++ timezone
---
(|PT24H| - (t2-t1))
This results in a response in seconds as 39600 which is 11 hours. I want the response to be as |PT11H| rather than 39600. It works when we convert seconds to hours when dividing by 3600 to 11 hours but we need that to be like |PT11H| rather than 39600.
Above input t1 and t2 comes from config. we can't change the setup.
You can use seconds function of the dw::core::Periods module. It takes the number of seconds as Parameter and returns a Period.
%dw 2.0
import seconds from dw::core::Periods
output application/java
var timezone = (now() >> "Pacific/Auckland") as String {format: "XXX"}
var t1 = '08:00:00.000' ++ timezone
var t2 = '21:00:00.000' ++ timezone
---
seconds( |PT24H| - (t2 - t1) )
Another suggestion, since you are working on time periods and time differences the timezone does not really matter. You can reduce your code to below datawave
%dw 2.0
import seconds from dw::core::Periods
output application/java
var t1 = '08:00:00.000' as Time
var t2 = '21:00:00.000' as Time
---
seconds( |PT24H| - (t2 - t1) )
The 'seconds' function is introduced in DataWeave version 2.4 and Mule Runtime 4.4 under the periodic module
Reference: seconds | MuleSoft Documentation https://docs.mulesoft.com/dataweave/2.4/dw-periods-functions-seconds
so if your Mule Runtime Version is lower than 4.4 then you have to go for dividing by 3600 as mentioned in the question itself.
Below is that solution too for developers who are using Mule Runtime Version lower than 4.4
First:
%dw 2.0
output application/java
var timezone = (now() >> "Pacific/Auckland") as String {format: "XXX"}
var t1 = '08:00:00.000' ++ timezone
var t2 = '21:00:00.000' ++ timezone
---
"|PT" ++ (|PT24H| - (t2-t1))/3600 ++ "H|"
Explanation: Since (|PT24H| - (t2-t1)) gives '39600' as the result which is in seconds, now to convert seconds to minutes you need to divide by 60, and then to convert minutes to hours you need to again divide by 60, So instead you can directly divide by (60 * 60 i.e. 3600) and get the hours.
as per suggestion in a comment if time is not in exact hours then we can use the below DataWeave script
Second:
%dw 2.0
output application/java
var timezone = (now() >> "Pacific/Auckland") as String {format: "XXX"}
var t1 = '08:00:00.000' ++ timezone
var t2 = '21:00:00.000' ++ timezone
---
"PT$(|PT24H| - (t2-t1))S" as Period

Date to DateTime conversion in DataWeave 2

Input date is coming in this format "2022-04-30" and I want to convert it to date time and time should be zeros like 2022-05-15T00:00:00Z.
How it can be achieved using DataWeave 2.0?
Convert the input string to a Date, then add the time to create a DateTime output. Then just convert to String. The default pattern seem to be adequate that you need.
%dw 2.0
output application/json
var sourceDate="2022-04-30"
---
(sourceDate as Date {format: "yyyy-MM-dd"} ++ |00:00:00Z|) as String
Output:
"2022-04-30T00:00:00Z"
If you want the result as String you can just Append "T00:00:00Z" to your date string
%dw 2.0
output application/json
var sourceDate="2022-04-30"
---
sourceDate ++ "T00:00:00Z"
And if you want a DateTime Object you can just coerce it to DateTime using as keyword. It will work as your date string is already in the required format.
%dw 2.0
output application/json
var sourceDate="2022-04-30"
---
(sourceDate ++ "T00:00:00Z") as DateTime

How do I convert a non zero padded day string to a useful date in pandas

I'm trying to import a date string with non-zero padded day, zero padded month, and year without century to create a datetime e.g. (11219 to 01/12/19). However, pandas cannot distinguish between the day and the month (e.g. 11219 could be 11th February, 2019 or 1st December, 2019).
I've tried using 'dayfirst' and the '#' in the day e.g. %#d, but nothing works. Code below, any advise?
Code:
df_import['newDate'] = pd.to_datetime(df_import['Date'], format='%d/%m/%Y', dayfirst = True)
Error:
time data '11219' does not match format '%d/%m/%Y' (match)
Since only the day is not zero-padded, the dates are unambiguous. They can simply be parsed by Pandas if we add the pad:
pd.to_datetime(df_import['Date'].str.zfill(6), format='%d%m%y')
use zfill()
A custom function can also be used if you want to handle more cases.
def getDate(str):
return #logic to parse
df_import['newDate'] = df_import['Date'].apply(getDate)

How to Change the date format yyyy/MM/dd HH:mm:ss to dd_mm_yy through modified java script value in pentaho

How to Change the date format yyyy/MM/dd HH:mm:ss to dd_mm_yy through modified java script value in pentaho?
Use this function in Modified Java Script Value step:
date2str(input, "dd_MM_yy");
You can use the SELECT step, and then in the Meta Data Tab, you can select the datatype as DATE and then use the format as "dd_MM_yy"
That's it, pretty simple :)
In pentaho a Date has always the time. There is not such thing as only date.
So, my guess would be that you need to format on output, converting it to a string for example.
But, if what you need is the date without the time, and by this i mean "yyyy/mm/dd 00:00:00", you can get it like this in Javascript:
var dateFieldValue=<yourdatecolumn>;
var year = dateFieldValue.getYear()+1900;
var month = dateFieldValue.getMonth();
var day = dateFieldValue.getDate();
var dateOnly = new Date(year,month,day);
or the last line could be:
var dateOnly = year + '-' + (month+1) + '-' + day;
if you want a String output like 'yyyy-mm-dd'
Hope this helps.