Use this in your clock.rb file:
require 'clockwork'
include ClockHelper
module Clockwork
# ...
every 1.day, "do_something", at: steps(every: 3.hours, aligned_at: '01:32') do
# do things ...
end
# ...
end| module ClockHelper | |
| # creates a list of 'HH:MM' for the `at:` option of `Clockwork.every` | |
| # | |
| # steps(every: 4.hours, aligned_at: '17:03') | |
| # #=> ["01:03", "05:03", "09:03", "13:03", "17:03", "21:03"] | |
| # steps(every: 2.hours, between: 12.hours..17.hours, aligned_at: '17:03') | |
| # #=> ["13:03", "15:03"] | |
| def steps(every:, aligned_at: '00:00', between: 0.hours...24.hours) | |
| beginning_of_day = aligned_at.to_time.beginning_of_day | |
| step_offset = (aligned_at.to_time.to_i + aligned_at.to_time.utc_offset) % every | |
| between.step(every). | |
| map { |step_in_between| (beginning_of_day + step_in_between + step_offset) }. | |
| select { |t| ((t.to_i + aligned_at.to_time.utc_offset) % 24.hours).in?(between) }. | |
| map { |t| t.strftime("%H:%M") } | |
| end | |
| end |
| require 'rails_helper' | |
| describe ClockHelper do | |
| subject { Class.new { include ClockHelper }.new } | |
| describe "#steps" do | |
| it "should align times throughout the day" do | |
| expect(subject.steps(every: 4.hours, aligned_at: "17:03")). | |
| to eq ["01:03", "05:03", "09:03", "13:03", "17:03", "21:03"] | |
| end | |
| context "with specific time span" do | |
| it "should also align times" do | |
| expect(subject.steps(every: 2.hours, between: 16.hours..20.hours, aligned_at: "17:03")). | |
| to eq ["17:03", "19:03"] | |
| end | |
| context "when time is outside of the span" do | |
| it "should also align times" do | |
| expect(subject.steps(every: 2.hours, between: 12.hours..17.hours, aligned_at: "17:03")). | |
| to eq ["13:03", "15:03"] | |
| end | |
| end | |
| context "when close to the end of day" do | |
| it "should also align times" do | |
| expect(subject.steps(every: 2.hours, between: 20.hours...24.hours, aligned_at: "17:03")). | |
| to eq ["21:03", "23:03"] | |
| end | |
| end | |
| end | |
| context "with < 1h intervals" do | |
| it do | |
| expect(subject.steps(every: 15.minutes, between: 12.hours...13.5.hours, aligned_at: "17:03")). | |
| to eq ["12:03", "12:18", "12:33", "12:48", "13:03", "13:18"] | |
| end | |
| end | |
| end | |
| end |