Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: TimeIterator -> TimeRange #18

Merged
merged 6 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
name: Ruby ${{ matrix.ruby }}
strategy:
matrix:
ruby: [3.0, 3.1, 3.2]
ruby: [2.7, 3.0, 3.1, 3.2, 3.3]

steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 4 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"MD046": false,
"MD013": false
}
5 changes: 4 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ require:

AllCops:
NewCops: enable
TargetRubyVersion: 3.0
TargetRubyVersion: 2.7

# Useful to separate conceptual expressions.
Layout/SpaceInsideArrayLiteralBrackets:
Expand All @@ -28,6 +28,9 @@ RSpec/ExampleLength:
RSpec/ExpectChange:
Enabled: false

RSpec/ImplicitSubject:
EnforcedStyle: single_statement_only

# Just one expectation per example is ambitious.
RSpec/MultipleExpectations:
Max: 5
Expand Down
1 change: 1 addition & 0 deletions .yardopts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--no-private
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

source "https://rubygems.org"

# Specify your gem's dependencies in time_iterator.gemspec
# Specify your gem's dependencies in time_range.gemspec
gemspec

gem "rake", "~> 13.0"
Expand Down
24 changes: 14 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
# TimeIterator
# TimeRange

TODO: Delete this and the text below, and describe your gem

Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/time_iterator`. To experiment with that code, run `bin/console` for an interactive prompt.
Range over Time using time intervals without ActiveSupport.

## Installation

TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.

Install the gem and add to the application's Gemfile by executing:

$ bundle add UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
bundle add time_range

If bundler is not being used to manage dependencies, install the gem by executing:

$ gem install UPDATE_WITH_YOUR_GEM_NAME_PRIOR_TO_RELEASE_TO_RUBYGEMS_ORG
gem install time_range

## Usage

TODO: Write usage instructions here
Works just like Range with one important change; **you must call `#by` to set a time interval.**

require 'time_range'

# Print the first day of each month of 2024.
time_range = TimeRange
.new(Time.local(2024), Time.local(2025), true)
.by(months: 1)
time_range.each { |time| puts time }

## Development

Expand All @@ -28,4 +32,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/schwern/ruby-time_iterator.
Bug reports and pull requests are welcome on GitHub at <https://github.com/schwern/ruby-time_range>.
2 changes: 1 addition & 1 deletion bin/console
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# frozen_string_literal: true

require "bundler/setup"
require "time_iterator"
require "time_range"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.
Expand Down
137 changes: 0 additions & 137 deletions lib/time_iterator.rb

This file was deleted.

71 changes: 71 additions & 0 deletions lib/time_range.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
require 'date'

require_relative 'time_range/advancer'
require_relative 'time_range/time'

# Range over Time stepping by time intervals.
#
# Does not require ActiveSupport.
#
# Unlike a Range, it is necessary to call #by to say how long between
# each step.
#
# @example Print every week of 2024.
# TimeRange
# .new(Time.local(2024), Time.local(2025), true)
# .by(weeks: 1)
# .each { |week| puts week }
class TimeRange < Range
# Same as Range.new, but it takes Time objects.
#
# @param first [Time] the beginning of the range
# @param last [Time] the end of the range
# @param exclude_last [Boolean] if true, exclude the last value from the range, default false
#
# @see Range.new
def initialize(first, last, exclude_last = false) # rubocop:disable Style/OptionalBooleanParameter
super(
first ? TimeRange::Time.new(first) : first,
last ? TimeRange::Time.new(last) : last,
exclude_last
)
end

# The time interval to use when iterating through the TimeRange.
#
# Returns the TimeRange object so you can safely chain
# time_range = TimeRange.new(...).by(...)
#
# Currently cannot be negative.
#
# @param seconds [Numeric]
# @param minutes [Numeric]
# @param hours [Numeric]
# @param days [Numeric]
# @param weeks [Numeric]
# @param months [Numeric]
# @param years [Numeric]
#
# @return [TimeRange] the TimeRange object
def by( # rubocop:disable Metrics/ParameterLists
seconds: nil, minutes: nil, hours: nil,
days: nil, weeks: nil, months: nil, years: nil
)
by = {
seconds: seconds, minutes: minutes, hours: hours,
days: days, weeks: weeks, months: months, years: years
}.compact!

self.begin&.by = by
self.end&.by = by

return self
end

# Like Range#eql?, but will be false if their #by is different.
def eql?(other)
return false if self.begin&.by != other.begin&.by || self.end&.by != other.end&.by

super
end
end
Loading
Loading