Date Continuity
This is a gem intended to handle start/end/duration DateTime calculations
Contents
- Installation
- Standalone
- Bundler
- Usage
- Example Usage
- Occurrence
- all_occurrences
- next_occurrence
- prev_occurrences
- Start Method
- End Method
- Duration Method
- Frequency Count Method
- Time Unit Method
- Configuration
- Example Configuration
Installation
Standalone
gem install date_continuity
Bundler
Add the gem to the Gemfile
source "https://rubygems.org"
gem "date_continuity"
And execute:
$ bundle
Usage
Include the DateContinuity::Model
in the model that you would like to use it with.
class Contract < ActiveRecord::Base
include DateContinuity::Model
end
Generate a migration to add the expected columns
$ rails generate add_start_at_end_on_and_duration_to_contracts start_at:datetime:index end_on:datetime:index duration:integer
and migrate
$ rails db:migrate
Example Usage
class Contract < ActiveRecord::Base
include DateContinuity::Model
private
def time_unit
"day"
end
end
$ contract = Contract.new(start_at: Date.new(2022, 2, 14), duration: 7)
$ contract.calc_end_at
=> Sun, 20 Feb 2022 00:00:00 +0000
Notice that this is not Date.new(2022, 2, 14) + 7.days
The end on is the LAST time the event happens, which would be Date.new(2022, 2, 14) + 7.days
A duration of 1 and a frequency of 1 would mean that the start/end would be the same.
By changing the frequency, it adjusts the calculated end_at date.
def frequency
0.5 # Every Other day
end
$ contract.calc_end_at
=> Sat, 26 Feb 2022 00:00:00 +0000
The object including DateContinuity::Model
needs to respond to a number of methods.
Occurrence
There are built in conveience methods to calculate and display occurrences.
All Occurrences
all_occurrences
returns an array of DateTime objects, starting with the start_at
DateTime, and incrementing based on on the frequency and time units, ending with the end_at
value.
Next Occurrence
next_occurrence
returns a DateTime object which represents the first value from #all_occurrences
that is greater than, or equal to the current DateTime.
It also accepts an optional DateTime argument which can be used to override the default, and find the next occurrence after the specified DateTime.
Prev Occurrence
prev_occurrence
returns a DateTime object which represents the last value from #all_occurrences
that is less than the current DateTime.
It also accepts an optional DateTime argument which can be used to override the default, and find the last occurrence before the specified DateTime.
Start
By default the start_method
is start_at
.
The start_method
value represents the time or date of the first occurrence.
It should return the same type as End. If this method returns a Date
object, the Time Unit can be configured for anything from a day
or larger, since a Date
cannot represent changes in units smaller than a day. If this method returns a Time
, or a DateTime
object, the Time Unit can be configured for any of the available units.
End
By default the end_method
is end_at
.
The end_method
value represents the time or date of the last occurrence.
It should return the same type as Start. If this method returns a Date
object, the Time Unit can be configured for anything from a day
or larger, since a Date
cannot represent changes in units smaller than a day. If this method returns a Time
, or a DateTime
object, the Time Unit can be configured for any of the available units.
Duration
By default the duration_method
is duration
.
The Duration is the number of times to repeat.
Frequency Count
By default the frequency_count_method
is frequency
. This is optional, and will default to 1, if no other frequency is specified.
Frequency is best thought of in terms of a fraction.
# A frequency of 1
1 == 1 / 1.0
"1 times per 1 time_unit"
# A frequency of 2
2 == 2 / 1.0
"2 times per 1 time_unit"
# A frequency of 0.5
0.5 == 0.5 / 1 == 1 / 2.0
"1 times per 2 time_units"
Time Unit
By default the time_unit_method
is time_unit
The time unit must be one of the following options: second minute hour day week month year
It will also accept pluralized options: seconds minutes hours days weeks months years
Configuration
Most everything is configurable. The methods don't even need to be database columns, so long as the object responds with the appropriate type and value.
Example Configuration
This example configuration file contains all the currently configurable settings and their defaults.
# config/initializers/date_continuity_initializer.rb
DateContinuity.configure do |config|
config.duration_method = :duration
config.end_method = :end_at
config.frequency_count_method = :frequency
config.start_method = :start_at
config.time_unit_method = :time_unit
end