Run a job every other monday - ruby

I would like to use Heroku scheduler to run every OTHER Monday. However, it only runs hourly, daily, every 10 minutes.
I read this...
How can I schedule a 'weekly' job on Heroku?
However, I'm not sure what code can be used. I think I can figure out every Monday, but not every OTHER Monday.
thanks

As you get more complicated, I'd recommend checking out scheduling gems. If you want to stick to vanilla Ruby, look at a combination of monday? and cweek, which tells you the week number in the current year. Run your job on Mondays in even-numbered weeks.
date = Date.today
date.monday? && date.cweek.even?
Note that cweek can return 53, since 365 isn't divisible by 7 and it has to handle that last, partial week. The new year's first week will be 1 (it doesn't count from 0), so you have to either skip a week or do two runs in a row when Monday falls in week 53.

Related

does monthlyOn() works with between in laravel scheduler?

I have made a custom command and want it to run on month last day at 02:00 but I also want it to run after that between some period of time like 02:00 till 15:00 following is my scheduler
`$schedule->command('billing:generate')
->monthlyOn(Carbon::now()->endOfMonth()->subHours(5)->format("d"), "02:00");`
now what I think Ill do to achieve this is like this:
$schedule->command('billing:generate')
->monthlyOn(Carbon::now()->endOfMonth()->subHours(5)->format("d"), "02:00")
->between("02:00", "15:00");
will it work as I want? I am on laravel version 6.
As you are on Laravel 6, you can schedule your command to run every day, but just check is that day the last day of the month, something like this:
// Runs exactly on "02:00" every month on its last day.
// (Actually runs every day, but doesn't execute if the day is not the last day of the month).
$schedule->command('billing:generate')->dailyAt('02:00')->when(function () {
return Carbon::now()->endOfMonth()->isToday();
});
// Runs between "02:00" and "15:00" every month on its last day.
// (Actually runs every day, but doesn't execute if the day is not the last day of the month).
$schedule->command('billing:generate')->daily()->between("02:00", "15:00")->when(function () {
return Carbon::now()->endOfMonth()->isToday();
});
If you are on newer versions of Laravel you can use lastDayOfMonth to which you can provide a time, and if needed, you can also chain between on it.
Also, to achieve what you want, you can specify 2 schedules and resolve the problem.
It should be like this:
// Runs exactly on "02:00" every month on its last day.
$schedule->command('billing:generate')->lastDayOfMonth("02:00");
// Runs between "02:00" and "15:00" every month on its last day.
$schedule->command('billing:generate')->lastDayOfMonth()->between("02:00", "15:00");

Power Automate Recurrence Trigger : how to find last 5 working days of the month?

I need to create a recurrence in Power Automate so that it only runs in the last 5 working days of the month. I can't use a generic rule because months like February are different.
What I have done so far was using a similar recurrence that finds the last working day of the month but need help with optimising it for the last 5 working days instead.
The logic is that the flow runs every day and looks at the first day of the next month, then comes backwards to find the first working day and excludes Monday-Sunday. however, I need it to find the last 5 working days instead of 1.
Also the functions used are like this:
startOfMonth(addToTime(variables('Date'),1,'Month'))
addDays(variables('DateCountDown'),-1)
dayOfWeek(variables('DateCountDown'))
#and(not(equals(variables('DayOfWeek'), 0)), not(equals(variables('DayOfWeek'), 6)))
addDays(variables('DateCountDown'), -1)
dayOfWeek(variables('DateCountDown'))
disclaimer: I am not a pro user of power automate and found this flow in an old GitHub repository (written by Michael Ziemba) - thanks all for your help.
in response to teylin:
I get today (as before)
I get first day of next month (as before)
I go 7 days down now > addDays(variables('DateCountDown'),-7)
I initialize a variable to find week day > dayOfWeek(variables('DateCountDown'))
then varCounter variable as you said (varCounter > integer > 1)
then DO UNTIL loop until varCounter = 7
inside the loop I have 3 conditions: day of week <> 0 , dayof week <> 6 and formatDateTime(variables('DateCountDown'), 'dd-MM-yyyy') = formatDateTime(variables('Date'), 'dd-MM-yyyy') (to check today)
then trigger my stuff if yes,
increment varCounter by 1
Don't overthink this. Conceptually:
Get the first day of the next month (you already know how to do this)
get DayX by subtracting 7 from that date (you already do this with 1, now do it with 7)
By definition, 2 of the seven days between that DayX and the next month will be on a weekend. So, next, you start a loop that runs 7 times. Inside the loop, you have these actions:
add a condition with the following two checks
check if DayX is a weekday (you already know how to do this) AND
check if DayX is = today
In the Yes branch of the condition run the steps that you want to run on the last 5 weekdays, in the No branch do nothing
below the condition step, increment DayX by one day
loop
For the loop, first initialise a counter variable to the value 1. Add a Do Until action and set it to run until the counter is greater than 7. Inside the loop, do your calculations and your condition etc. As the last step of the loop, increment the counter variable by 1.

Laravel Scheduler monthlayAt weekdays combination

I'm quite new to the Laravel Scheduler. Currently there's an email sent out every 1st day of the month like this:
$schedule->job(new SendMonthlyUpdate)
->monthlyOn(1, '9:00')
->timezone('Europe/Amsterdam');
How would I change this if I want to always send it on the 1st day of the month, EXCEPT from weekends? In case the 1st (or 2nd) day is in a weekend, it should be triggered on Monday after the weekend.
I was considering something like this:
$schedule->job(new SendMonthlyUpdate)
->monthlyOn(1, '9:00')
->weekdays()
->timezone('Europe/Amsterdam');
But I'm not sure if:
A. This will entirely skip this job if the 1st day is in the weekend, rather than sending it later?
B. How to test this
Any help would be appreciated!
It's even simpler than that:
$schedule->job(new SendMonthlyUpdate)
->monthly()
->weekdays();
Should do the job once per month as soon as it's a weekday.
In order to test it you will have to change the date of your system.

How to get user hour of the week in Ruby

I want to get the current hour of the week in which day starts from Sunday.
Consider current time is
Time.now
=> 2014-10-29 12:09:23PM +0530
The result should be : 84
Explanation:
Sunday - 24 hours
Monday - 24 hours
Tuesday - 24hours
Wednesday - 12 hours
Total: 84
How can get the user hour of the week. Is there any method available in Ruby ? Or how to do it without Ruby method.
You can get the day of the week and hour of the day using Time#wday and Time#hour.
Time.now.wday
#=> 3
Time.now.hour
#=> 14
The rest is basic mathematics.
Even though I upvoted Yu Hao, I must say it's not a good approach if you want to pay attention to the concerns Jon Skeet raised. To that end, here's another approach:
(Time.now - (Date.today - Date.today.wday).to_time) / 3600
Date.today is, well, today. If you subtract the number of days since the week started, you get Sunday. Convert it to Time and it's the midnight when Sunday began. Subtraction gives you number of seconds between then and now. Divide by 3600 (and optionally round) to get number of hours. The DST details should be transparently handled by Time#-.
EDIT: Timezones... Run this before:
ENV['TZ']='EST5EDT'
(be sure to reset it back to what it used to be afterwards, in case anyone else needs to know time and didn't count on you switching timezones.) You can also use "America/New_York" instead. See tz list for details.

Can I specify week 0 in ice_cube gem when I want to a job to run every 2 weeks?

I have this recurring job in our Rails service that sends out emails on Friday every two weeks. However, based on our business requirement, the first week of the "every two weeks" schedule should be this week, which means the email should be sent out this Friday, and then 2 weeks after that, and 4 weeks after that, etc.
The schedule shouldn't be broken when the service restarts. For example, after the email is sent out this Friday, if I restart the service on Saturday, it shouldn't schedule the job to Friday next week -- should still be the Friday of the week after next week. In short, the week 0 should be persistent and stick to this week.
Is it doable in ice_cube? Or are there any other better solution? Thank!
Setting "week 0" is built into IceCube. When you create the schedule, specify the start time rather than Time.now.
2.1.4 :012 > s = IceCube::Schedule.new(Time.now.beginning_of_month)
2.1.4 :013 > s.add_recurrence_rule IceCube::Rule.monthly.count(3)
2.1.4 :014 > s.all_occurrences
=> [2014-12-01 00:00:00 -0500, 2015-01-01 00:00:00 -0500, 2015-02-01 00:00:00 -0500]
Here, I told IceCube the schedule starts at the beginning of this month, although I could have used any value. IceCube computes the schedule based on that time, giving me Dec 1, Jan 1, and Feb 1.

Resources