Need Freemarker method/function to detect US holiday name from a given date - freemarker

Does anyone know of a Freemarker function/method that returns the name of a US holiday for a given date?
I've written a function to retrieve the previous business day (Mon-Fri) for any given date, but if the previous business day happens to be one of ten recognized holidays at our company, then I need to step back one day from that to then run my getPreviousBusinessDay function.
Here is my getPreviousBusinessDay function:
<#function getPreviousBusinessDay date>
<#local dateAsEpochMS = date?long> <#-- Convert date to epoch time in milliseconds -->
<#local outie = ""/>
<#local dayOfWeek = date?string("EEEE")>
<#if dayOfWeek = "Monday">
<#local outie = dateAsEpochMS - 259200000> <#-- subtract 3 days in milliseconds -->
<#elseif dayOfWeek = "Sunday">
<#local outie = dateAsEpochMS - 172800000> <#-- subtract 2 days in milliseconds -->
<#else>
<#local outie = dateAsEpochMS - 86400000> <#-- subtract 1 days in milliseconds -->
</#if>
<#local outie = outie?number_to_date?string("MMMM d, YYYY")>
<#return outie>
</#function>
So if you enter "August 1, 2022" (a Monday) into the function:
${getPreviousBusinessDay("August 1, 2022"?date)}
it returns the previous Friday date:
July 29, 2022
That's all well and good, but hence my problem if the previous business day happens to be one of those ten holidays that we're closed.
Any ideas?

You could create a <#function isBusinessDay(date)>, that returns true for days that aren't weekend days, and not in the set of knows corporate holidays. Then in getPreviousBusinessDay you just step back one day in a loop until isBusinessDay(date) returns true.
But, where/how is the information about the corporate holydays stored? Also it will be different each year, so it's something that will have to be updated time to time.
BTW, doing logic like this in templates is bad practice. I would create some service in Java that can answer all these questions, and just call that.
Also be careful with substracting one day in millies. That can break if you are using a time zone that day light saving, and you date-time is near midnight.

Related

Can't get monthy CarbonPeriod to behave as desired

In the project I'm working on I have a daily command that basically checks the date of the last record in the database and tries to fetch data from an API from the day after and then each month after that (the data is published monthly).
Basically, the last record's date is 2019-08-30. I'm mocking as if I were running the task on 2019-09-01 with
$test = Carbon::create(2019,9,1,4);
Carbon::setTestNow($test);
I then create a monthly period between the next day of the last record's date and the last day of the current month like so:
$period = CarbonPeriod::create($last_record_date->addDay(), '1 month', $last_day_of_current_month);
Successfully generating a period with start_date = 2019-08-31 and end_date = 2019-09-30. Which I use in a simple foreach.
What I expected to happen is that it runs twice, once for August and once for September, but it's running only once for the start date. It's probably adding a month and going past the end date, but I don't know how to force the behaviour I'm looking for.
TL;DR:
$period = CarbonPeriod::create('2019-08-31', '1 month', '2019-09-30');
foreach ($period as $dt) {
echo $dt->format("Y-m") . "<br>\n";
}
This will print just 2019-08, while I expect 2019-08 and 2019-09. What's the best way to achieve that?
Solution :-
You can store actual date in $actual_day and current date for occurring monthly in $current_day. Put a check on comparing both dates, if not matched then make it on the same day it will skip 30,31 case in case of February month.
$current_date = $current_date->addMonths(1);
if($current_date->day != $actual_day){
$date = Carbon::parse($date->year."-".$date->month."-".$actual_day);
}
Your start date is 2019-08-31. Adding a month takes you to 2019-09-31. 2019-09-31 doesn't exist so instead you get 2019-10-01, which is after your end date. To avoid this I'd suggest you use a more regular interval such as 30 days.
Otherwise you're going to have to rigorously define what you mean by "a month later". If the start date is 31st Jan is the next date 28th February? Is the month after 28th or 31st March? How do leap years affect things?

Get a Specific WeekDay date after a date

I am trying to implement a delivery process that occurs at specific days of week for each region. So, in a Region that delivers on Tuesdays and Thursdays I need to be able to get next eligible date based on the date the product will be available. So, if I will have it read on the 5th, O need to get the date for the next Tuesday or Thursday.
I started implementing it on Carbon, but I and creating a lot of loops through dates, testing dates and checking if its valid. something of getting product availability date and checking each day after it if its a monday Tuesday or Thursday ... etc ///I am sure, using Carbon, will have a better way to do it.
Any hint on how to do that ?
Thanks for any help!
Define a date:
$date = Carbon::now();
Now you have to get the day:
$day = $date->dayOfWeekIso
If $date is monday, then you will get a integer and that would be 1. That is because: 1 (monday), 2 (Tuesday), ..., 7 (sunday).
Now that you have this number you just need to apply some simple logic.
If the number you get is a 2 (Tuesday) then you will need to add two days to your $date in order to get the delivery date:
$delivery_date = $date->addDays(2);
If your day is equal 4 (Thursday), then you need to add 6 days to your $date so that would give you the next Tuesday:
$delivery_date = $date->addDays(6);
I think that's what you want! I hope it helps!

Does LUIS recognizes multiple same Pre Built entities in utterances

Utterance :
I want to book a flight from Hyderabad to Bangalore next Monday preferably around afternoon with a return on next Friday preferably around evening .
Entities:
FromDestination : Hyderabad,
ToDestination: Bangalore
Prebuilt Enties:
Buiiltin.DateTimeV2 : Next Monday, Friday.
Builtin.DateTimeV2.TimeRange : Afternoon , Evening
.NET Code to recognize enties:
foreach(EntityRecommendation obj in result.Entities)
{
if(obj.Type == FlightBotConstants.fromDestination)
{
context.PrivateConversationData.SetValue<string>("fromDestination", Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(obj.Entity.ToLower()));
}
else if(obj.Type == FlightBotConstants.toDestination)
{
context.PrivateConversationData.SetValue<string>("toDestination", Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(obj.Entity.ToLower()));
}
else if(obj.Type == FlightBotConstants.prebuiltdate)
{
Chronic.Parser depparser = new Chronic.Parser();
var depDateResult = depparser.Parse(obj.Entity);
string departureDate = depDateResult.Start.Value.ToString("yyyy-MM-dd");
context.PrivateConversationData.SetValue<string>("departtDate", Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(departureDate));
}
else if(obj.Type == FlightBotConstants.prebuilttimeRange)
{
Chronic.Parser depTimeParser = new Chronic.Parser();
var deptimeResult = depTimeParser.Parse(obj.Entity);
var depStartTime = deptimeResult.Start.Value.TimeOfDay;
var depEndTime = deptimeResult.End.Value.TimeOfDay;
context.PrivateConversationData.SetValue<string>("departureStartTime", Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(depStartTime.ToString()));
context.PrivateConversationData.SetValue<string>("departureEndTime", Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(depEndTime.ToString()));
}
}
I need a output like below. How i can get exactly
Departing Location: Hyderabad
Arrival Location: Bangalore
Date of Departure: 2018-01-15
Departure Start Time: 13:00
Departure End Time: 18:00
Date of Return: 2018-01-19
Return Start Time: 19:00
Departure End Time: 22:00
I can get all entities data, but my issue is if user utterance is " I want to book a flight from Hyderabad to Bangalore next Monday with a return on next Friday preferably around evening".
How exactly i can write my code to get below output.
Departing Location: Hyderabad
Arrival Location: Bangalore
Date of Departure: 2018-01-15
Departure Start Time:
Departure End Time:
Date of Return: 2018-01-19
Return Start Time: 19:00
Departure End Time: 22:00
Can you provide an example of what the entities returned are?
Without knowing what the LUIS model I can only offer a few tips:
If you are correctly getting all entities, you can add the entities in a temporary list/container in your bot and then format it to suit your scenario.
You can try training your LUIS model around composite entities. This will allow you to associate your custom entities (FromDestination, ToDestination) with the pre-built entity of datetime.
Hope that helps
for good LUIS will identify referential day/week/month/Year
like,
datetimeV2 --> last year, datetimeV2 --> Previous year,
datetimeV2 --> next month, datetimeV2 --> last month,
datetimeV2 --> last week, datetimeV2 --> next week,
datetimeV2 --> previous day, datetimeV2 --> early next week,
datetimeV2 --> next day, datetimeV2 --> yesterday,
datetimeV2 --> tomorrow, datetimeV2 --> day before yesterday,
datetimeV2 --> day after tomorrow,
so and so forth
Similarly,
datetimeV2 --> tomorrow morning, datetimeV2 --> early morning tomorrow,
datetimeV2 --> today early evening,
so and so forth,
for your query " I want to book a flight from Hyderabad to Bangalore next Monday with a return on next Friday preferably around evening"
you can refer calendar for datetimeV2 -->next Monday and datetimeV2 --> next Friday and identify applicable appropriate dates.
when user referred Morning or evening acknowledged the input and prompt user to specify the timings.
After all, a bot is a conversational interface, it has to ask questions and seek clarifications to help users to accomplish their objective.

VBScript DateDiff month

I am having a problem about getting the month datedifference between two dates.
Here is a sample:
DateDiff("m","2014-10-17","2014-10-30")
The above code returns 0 months since it is less than a month. But,
DateDiff("m","2014-10-17","2014-11-01")
returns 1 which should not be since it is still 15 days.
My problem is I want to see if these two dates already exceed a month but it seems that it calculates 1 month only when the month part of the date is changed.
DateDiff calculates the span between two timestamps with the precision defined in the first parameter. From what you described in your question and comments you rather seem to be looking for something like this:
ds1 = "2014-10-17"
ds2 = "2014-10-30"
d1 = CDate(ds1)
d2 = CDate(ds2)
diff = DateDiff("m", d1, d2)
If diff > 0 And Day(d2) < Day(d1) Then diff = diff - 1
WScript.Echo diff & " full months have passed between " & ds1 & " and " & ds2 & "."
You can calculate day difference between two dates using 'DateDiff("d",date1,date2)'.
Then calculate number of full-month by dividing 30 days.
Following is an example.
monthDiff = int(DateDiff("d","2014-10-17","2014-11-01") / 30)
As you know, days of months differs by month. For example, November has 30 days and December has 31 days.
If you wish to use 30 days a month when first day is on November, and to use 31 days a month whe first day is on December, the code need a table of days of months and routine to handle month information.

Determine the amount of clicks required to reach a specific date using a JQuery calendar?

I have a jquery calendar for the start date of a project.
Using Watir (automated browser driver, a gem for ruby), I have a set date that I would like to enter in.
The calendar start date is always today's date, whatever that may be for the day it is used. I was wondering if there was a way that ruby can process what today's date is, and use the specified date provided by the user, to calculate the difference of months between them.
Here is an example of the Calendar plugin: http://jqueryui.com/datepicker/
example:
today's date is 30/10/2012, if there was a project that were to start on the 20/12/2012, that would be 2 months from now, so 2 clicks on the next month button.
Is there a way I could do this?
Here is how I approached a similar situation with JSdatepicker:
$today = Time.now.strftime("%e").gsub(" ", "") #one digit day of month without leading space
#browser.text_field(:id => /dateAvailable/).click
Watir::Wait.until(60) {#browser.div(:id => /dateAvailable_popup_cal/).td(:text => $today).exists?}
#browser.div(:id => /dateAvailable_popup_cal/).td(:text => $today).click
Set or grab the date.
Click the text_field that fires the JSDatePicker object
Wait until the calendar actually pops up
The current month is shown, so choose today's date number.
In your case, you also need to set the month. Whether prompting the user for this, or choosing "today", the theory is the same:
$month = Date::MONTHNAMES[Date.today.month] #etc
Pseudo-code making lots of assumptions (only future dates, month name shown on calendar as text, etc):
while !#jquerytablewindow.text.include?($month)
next_month_button.click
end
I don't see a specific advantage to my method versus counting each month, unless of course we add a month to the calendar one day and you still want your code to work!
You could do:
#End date converted to date object
specified_date = '20/12/2012'
end_date = Date.parse(specified_date)
#Start date (today - 30/10/2012)
today = Date.today
#Determine difference in months
number_of_months_up_to_today = (today.month + today.year * 12)
number_of_months_up_to_end = (end_date.month + end_date.year * 12)
clicks_required = number_of_months_up_to_end - number_of_months_up_to_today
#=> 2
Basically it is counting the number of months since the year 0 and then finding the difference.

Resources