by_star 3.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/mysql.yml +92 -0
  3. data/.github/workflows/postgresql.yml +99 -0
  4. data/.gitignore +6 -5
  5. data/.travis.yml +92 -61
  6. data/CHANGELOG.md +63 -44
  7. data/Gemfile +18 -18
  8. data/MIT-LICENSE +20 -20
  9. data/README.md +616 -577
  10. data/Rakefile +18 -18
  11. data/UPGRADING +4 -6
  12. data/by_star.gemspec +34 -34
  13. data/cleaner.rb +24 -24
  14. data/lib/by_star/base.rb +69 -68
  15. data/lib/by_star/between.rb +185 -156
  16. data/lib/by_star/directional.rb +35 -37
  17. data/lib/by_star/kernel/date.rb +41 -50
  18. data/lib/by_star/kernel/in_time_zone.rb +20 -0
  19. data/lib/by_star/kernel/time.rb +41 -41
  20. data/lib/by_star/normalization.rb +156 -127
  21. data/lib/by_star/orm/active_record/by_star.rb +75 -61
  22. data/lib/by_star/orm/mongoid/by_star.rb +90 -76
  23. data/lib/by_star/orm/mongoid/reorder.rb +23 -23
  24. data/lib/by_star/version.rb +3 -3
  25. data/lib/by_star.rb +18 -17
  26. data/spec/database.yml +15 -15
  27. data/spec/fixtures/active_record/models.rb +12 -12
  28. data/spec/fixtures/active_record/schema.rb +19 -19
  29. data/spec/fixtures/mongoid/models.rb +31 -31
  30. data/spec/fixtures/shared/seeds.rb +36 -26
  31. data/spec/gemfiles/Gemfile.rails +5 -0
  32. data/spec/gemfiles/Gemfile.rails32 +7 -0
  33. data/spec/gemfiles/Gemfile.rails40 +7 -7
  34. data/spec/gemfiles/Gemfile.rails41 +7 -7
  35. data/spec/gemfiles/Gemfile.rails42 +7 -7
  36. data/spec/gemfiles/Gemfile.rails50 +7 -10
  37. data/spec/gemfiles/Gemfile.rails51 +7 -10
  38. data/spec/gemfiles/Gemfile.rails52 +7 -0
  39. data/spec/gemfiles/Gemfile.rails60 +7 -0
  40. data/spec/gemfiles/Gemfile.rails61 +7 -0
  41. data/spec/integration/active_record/active_record_spec.rb +41 -38
  42. data/spec/integration/mongoid/mongoid_spec.rb +39 -37
  43. data/spec/integration/shared/at_time.rb +53 -0
  44. data/spec/integration/shared/between_dates.rb +99 -0
  45. data/spec/integration/shared/between_times.rb +99 -82
  46. data/spec/integration/shared/by_calendar_month.rb +55 -55
  47. data/spec/integration/shared/by_cweek.rb +54 -54
  48. data/spec/integration/shared/by_day.rb +120 -96
  49. data/spec/integration/shared/by_direction.rb +126 -172
  50. data/spec/integration/shared/by_fortnight.rb +48 -48
  51. data/spec/integration/shared/by_month.rb +50 -50
  52. data/spec/integration/shared/by_quarter.rb +49 -49
  53. data/spec/integration/shared/by_week.rb +54 -54
  54. data/spec/integration/shared/by_weekend.rb +49 -49
  55. data/spec/integration/shared/by_year.rb +48 -48
  56. data/spec/integration/shared/index_scope_parameter.rb +111 -0
  57. data/spec/integration/shared/offset_parameter.rb +32 -32
  58. data/spec/integration/shared/order_parameter.rb +36 -36
  59. data/spec/integration/shared/relative.rb +174 -174
  60. data/spec/spec_helper.rb +33 -29
  61. data/spec/unit/kernel_date_spec.rb +113 -113
  62. data/spec/unit/kernel_time_spec.rb +57 -57
  63. data/spec/unit/normalization_spec.rb +384 -305
  64. data/tmp/.gitignore +1 -1
  65. metadata +33 -21
  66. data/spec/gemfiles/Gemfile.master +0 -6
  67. data/spec/integration/shared/scope_parameter.rb +0 -73
data/Rakefile CHANGED
@@ -1,18 +1,18 @@
1
- require 'bundler'
2
- require 'rspec/core/rake_task'
3
-
4
- Bundler::GemHelper.install_tasks
5
- RSpec::Core::RakeTask.new(:spec)
6
-
7
- def orm_test(orm)
8
- RSpec::Core::RakeTask.new(orm) do |task|
9
- task.pattern = "./spec/{unit,integration/#{orm}}/{,/*/**}/*_spec.rb"
10
- end
11
- end
12
-
13
- namespace :spec do
14
- orm_test 'active_record'
15
- orm_test 'mongoid'
16
- end
17
-
18
- task default: :spec
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+
4
+ Bundler::GemHelper.install_tasks
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ def orm_test(orm)
8
+ RSpec::Core::RakeTask.new(orm) do |task|
9
+ task.pattern = "./spec/{unit,integration/#{orm}}/{,/*/**}/*_spec.rb"
10
+ end
11
+ end
12
+
13
+ namespace :spec do
14
+ orm_test 'active_record'
15
+ orm_test 'mongoid'
16
+ end
17
+
18
+ task default: :spec
data/UPGRADING CHANGED
@@ -1,6 +1,4 @@
1
- Upgrading ByStar
2
- ----------------
3
-
4
- * Chronic gem (used for time string parsing) has been removed as a hard dependency for ByStar,
5
- however it is still supported. If you would like to use Chronic with ByStar, please explicitly
6
- include `gem chronic` into your Gemfile.
1
+ Upgrading ByStar
2
+ ----------------
3
+
4
+ * As of version 4.0.0, ByStar changes the way it handles `Date` arg to the `#between_times` method. If a `Date` is given as the second (end) arg, the query will use `Date.end_of_day` to include all time values which fall inside that date.
data/by_star.gemspec CHANGED
@@ -1,34 +1,34 @@
1
- # -*- encoding: utf-8 -*-
2
- require File.expand_path("../lib/by_star/version", __FILE__)
3
-
4
- Gem::Specification.new do |s|
5
- s.name = "by_star"
6
- s.version = ByStar::VERSION
7
- s.authors = ["Ryan Bigg", "Johnny Shields"]
8
- s.email = ["radarlistener@gmail.com"]
9
- s.homepage = "http://github.com/radar/by_star"
10
- s.summary = "ActiveRecord and Mongoid extension for easier date scopes and time ranges"
11
- s.description = "ActiveRecord and Mongoid extension for easier date scopes and time ranges"
12
-
13
- s.required_ruby_version = '>= 2.0.0'
14
-
15
- s.post_install_message = File.read('UPGRADING') if File.exists?('UPGRADING')
16
-
17
- s.add_dependency "activesupport", "> 3"
18
-
19
- s.add_development_dependency "chronic"
20
- s.add_development_dependency "bundler"
21
- s.add_development_dependency "sqlite3"
22
- s.add_development_dependency "activerecord"
23
- s.add_development_dependency "mongoid"
24
- s.add_development_dependency "pg"
25
- s.add_development_dependency "mysql2", "~> 0.3.10"
26
- s.add_development_dependency "rspec-rails", "~> 3.1"
27
- s.add_development_dependency "timecop", "~> 0.3"
28
- s.add_development_dependency "pry"
29
-
30
- s.files = `git ls-files`.split($/)
31
- s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
- s.test_files = s.files.grep(%r{^(test|spec|features)/})
33
- s.require_paths = ['lib']
34
- end
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/by_star/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "by_star"
6
+ s.version = ByStar::VERSION
7
+ s.authors = ["Ryan Bigg", "Johnny Shields"]
8
+ s.email = ["radarlistener@gmail.com"]
9
+ s.homepage = "http://github.com/radar/by_star"
10
+ s.summary = "ActiveRecord and Mongoid extension for easier date scopes and time ranges"
11
+ s.description = "ActiveRecord and Mongoid extension for easier date scopes and time ranges"
12
+
13
+ s.required_ruby_version = '>= 2.0.0'
14
+
15
+ s.post_install_message = File.read('UPGRADING') if File.exist?('UPGRADING')
16
+
17
+ s.add_dependency "activesupport", ">= 3.2.0"
18
+
19
+ s.add_development_dependency "chronic"
20
+ s.add_development_dependency "bundler"
21
+ s.add_development_dependency "sqlite3"
22
+ s.add_development_dependency "activerecord"
23
+ s.add_development_dependency "mongoid"
24
+ s.add_development_dependency "pg"
25
+ s.add_development_dependency "mysql2"
26
+ s.add_development_dependency "rspec-rails", "~> 3.1"
27
+ s.add_development_dependency "timecop", "~> 0.3"
28
+ s.add_development_dependency "pry"
29
+
30
+ s.files = `git ls-files`.split($/)
31
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
32
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
33
+ s.require_paths = ['lib']
34
+ end
data/cleaner.rb CHANGED
@@ -1,25 +1,25 @@
1
- files = Dir["**/*"]
2
- ignored_files = [
3
- /log\/.*/,
4
- ]
5
-
6
- files.delete_if do |file|
7
- if File.directory?(file)
8
- true
9
- else
10
- ignored_files.any? do |condition|
11
- if condition.is_a?(String)
12
- file == condition
13
- else
14
- condition.match(file)
15
- end
16
- end || false
17
- end
18
- end
19
-
20
- for file in files - ignored_files
21
- if File.file?(file)
22
- lines = File.readlines(file).map { |line| line.gsub(/^\s+$/, "\n") }
23
- File.open(file, "w+") { |f| f.write(lines.join) }
24
- end
1
+ files = Dir["**/*"]
2
+ ignored_files = [
3
+ /log\/.*/,
4
+ ]
5
+
6
+ files.delete_if do |file|
7
+ if File.directory?(file)
8
+ true
9
+ else
10
+ ignored_files.any? do |condition|
11
+ if condition.is_a?(String)
12
+ file == condition
13
+ else
14
+ condition.match(file)
15
+ end
16
+ end || false
17
+ end
18
+ end
19
+
20
+ for file in files - ignored_files
21
+ if File.file?(file)
22
+ lines = File.readlines(file).map { |line| line.gsub(/^\s+$/, "\n") }
23
+ File.open(file, "w+") { |f| f.write(lines.join) }
24
+ end
25
25
  end
data/lib/by_star/base.rb CHANGED
@@ -1,68 +1,69 @@
1
- module ByStar
2
-
3
- module Base
4
-
5
- include ByStar::Between
6
- include ByStar::Directional
7
-
8
- def by_star_field(*args)
9
- options = args.extract_options!
10
- @by_star_start_field ||= args[0]
11
- @by_star_end_field ||= args[1]
12
- @by_star_offset ||= options[:offset]
13
- @by_star_scope ||= options[:scope]
14
- end
15
-
16
- def by_star_offset(options = {})
17
- (options[:offset] || @by_star_offset || 0).seconds
18
- end
19
-
20
- def by_star_start_field(options={})
21
- field = options[:field] ||
22
- options[:start_field] ||
23
- @by_star_start_field ||
24
- by_star_default_field
25
- field.to_s
26
- end
27
-
28
- def by_star_end_field(options={})
29
- field = options[:field] ||
30
- options[:end_field] ||
31
- @by_star_end_field ||
32
- by_star_start_field
33
- field.to_s
34
- end
35
-
36
- def by_star_scope(options={})
37
- scope = options[:scope] || @by_star_scope || self
38
- if scope.is_a?(Proc)
39
- if scope.arity == 0
40
- return instance_exec(&scope)
41
- elsif options[:scope_args]
42
- return instance_exec(*Array(options[:scope_args]), &scope)
43
- else
44
- raise 'ByStar :scope Proc requires :scope_args to be specified.'
45
- end
46
- else
47
- return scope
48
- end
49
- end
50
-
51
- protected
52
-
53
- # Wrapper function which extracts time and options for each by_star query.
54
- # Note the following syntax examples are valid:
55
- #
56
- # Post.by_month # defaults to current time
57
- # Post.by_month(2, year: 2004) # February, 2004
58
- # Post.by_month(Time.now)
59
- # Post.by_month(Time.now, field: "published_at")
60
- # Post.by_month(field: "published_at")
61
- #
62
- def with_by_star_options(*args, &block)
63
- options = args.extract_options!.symbolize_keys!
64
- time = args.first || Time.zone.now
65
- block.call(time, options)
66
- end
67
- end
68
- end
1
+ module ByStar
2
+
3
+ module Base
4
+
5
+ include ByStar::Between
6
+ include ByStar::Directional
7
+
8
+ def by_star_field(*args)
9
+ options = args.extract_options!
10
+ @by_star_start_field ||= args[0]
11
+ @by_star_end_field ||= args[1]
12
+ @by_star_offset ||= options[:offset]
13
+ @by_star_scope ||= options[:scope]
14
+ @by_star_index_scope ||= options[:index_scope]
15
+ end
16
+
17
+ def by_star_offset(options = {})
18
+ (options[:offset] || @by_star_offset || 0).seconds
19
+ end
20
+
21
+ def by_star_start_field(options={})
22
+ field = options[:field] ||
23
+ options[:start_field] ||
24
+ @by_star_start_field ||
25
+ by_star_default_field
26
+ field.to_s
27
+ end
28
+
29
+ def by_star_end_field(options={})
30
+ field = options[:field] ||
31
+ options[:end_field] ||
32
+ @by_star_end_field ||
33
+ by_star_start_field
34
+ field.to_s
35
+ end
36
+
37
+ protected
38
+
39
+ # Wrapper function which extracts time and options for each by_star query.
40
+ # Note the following syntax examples are valid:
41
+ #
42
+ # Post.by_month # defaults to current time
43
+ # Post.by_month(2, year: 2004) # February, 2004
44
+ # Post.by_month(Time.now)
45
+ # Post.by_month(Time.now, field: "published_at")
46
+ # Post.by_month(field: "published_at")
47
+ #
48
+ def with_by_star_options(*args, &block)
49
+ options = args.extract_options!.symbolize_keys!
50
+ time = args.first || Time.zone.now
51
+ block.call(time, options)
52
+ end
53
+
54
+ def by_star_eval_index_scope(start_time, end_time, options)
55
+ value = options[:index_scope] || @by_star_index_scope
56
+ value = value.call(start_time, end_time, options) if value.is_a?(Proc)
57
+ case value
58
+ when nil, false then nil
59
+ when Time, DateTime, Date then value.in_time_zone
60
+ when ActiveSupport::Duration then start_time - value
61
+ when Numeric then start_time - value.seconds
62
+ when :beginning_of_day
63
+ offset = options[:offset] || 0
64
+ (start_time - offset).beginning_of_day + offset
65
+ else raise 'ByStar :index_scope option value is not a supported type.'
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,156 +1,185 @@
1
- module ByStar
2
-
3
- module Between
4
-
5
- def between_times(*args)
6
- options = args.extract_options!.symbolize_keys!
7
-
8
- start_time, end_time = case args[0]
9
- when Array, Range then [args[0].first, args[0].last]
10
- else args[0..1]
11
- end
12
-
13
- offset = (options[:offset] || 0).seconds
14
- start_time += offset if start_time
15
- end_time += offset if end_time
16
-
17
- start_field = by_star_start_field(options)
18
- end_field = by_star_end_field(options)
19
- scope = by_star_scope(options)
20
-
21
- scope = if !start_time && !end_time
22
- scope # do nothing
23
- elsif !end_time
24
- by_star_after_query(scope, start_field, start_time)
25
- elsif !start_time
26
- by_star_before_query(scope, start_field, end_time)
27
- elsif start_field == end_field
28
- by_star_point_query(scope, start_field, start_time, end_time)
29
- elsif options[:strict]
30
- by_star_span_strict_query(scope, start_field, end_field, start_time, end_time)
31
- else
32
- by_star_span_overlap_query(scope, start_field, end_field, start_time, end_time, options)
33
- end
34
-
35
- scope = by_star_order(scope, options[:order]) if options[:order]
36
-
37
- scope
38
- end
39
-
40
- def by_day(*args)
41
- with_by_star_options(*args) do |time, options|
42
- time = ByStar::Normalization.time(time)
43
- between_times(time.beginning_of_day, time.end_of_day, options)
44
- end
45
- end
46
-
47
- def by_week(*args)
48
- with_by_star_options(*args) do |time, options|
49
- time = ByStar::Normalization.week(time, options)
50
- start_day = Array(options[:start_day])
51
- between_times(time.beginning_of_week(*start_day), time.end_of_week(*start_day), options)
52
- end
53
- end
54
-
55
- def by_cweek(*args)
56
- with_by_star_options(*args) do |time, options|
57
- by_week(ByStar::Normalization.cweek(time, options), options)
58
- end
59
- end
60
-
61
- def by_weekend(*args)
62
- with_by_star_options(*args) do |time, options|
63
- time = ByStar::Normalization.week(time, options)
64
- between_times(time.beginning_of_weekend, time.end_of_weekend, options)
65
- end
66
- end
67
-
68
- def by_fortnight(*args)
69
- with_by_star_options(*args) do |time, options|
70
- time = ByStar::Normalization.fortnight(time, options)
71
- between_times(time.beginning_of_fortnight, time.end_of_fortnight, options)
72
- end
73
- end
74
-
75
- def by_month(*args)
76
- with_by_star_options(*args) do |time, options|
77
- time = ByStar::Normalization.month(time, options)
78
- between_times(time.beginning_of_month, time.end_of_month, options)
79
- end
80
- end
81
-
82
- def by_calendar_month(*args)
83
- with_by_star_options(*args) do |time, options|
84
- time = ByStar::Normalization.month(time, options)
85
- start_day = Array(options[:start_day])
86
- between_times(time.beginning_of_calendar_month(*start_day), time.end_of_calendar_month(*start_day), options)
87
- end
88
- end
89
-
90
- def by_quarter(*args)
91
- with_by_star_options(*args) do |time, options|
92
- time = ByStar::Normalization.quarter(time, options)
93
- between_times(time.beginning_of_quarter, time.end_of_quarter, options)
94
- end
95
- end
96
-
97
- def by_year(*args)
98
- with_by_star_options(*args) do |time, options|
99
- time = ByStar::Normalization.year(time, options)
100
- between_times(time.beginning_of_year, time.end_of_year, options)
101
- end
102
- end
103
-
104
- def today(options={})
105
- by_day(Time.zone.now, options)
106
- end
107
-
108
- def yesterday(options={})
109
- by_day(Time.zone.now.yesterday, options)
110
- end
111
-
112
- def tomorrow(options={})
113
- by_day(Time.zone.now.tomorrow, options)
114
- end
115
-
116
- def past_day(options={})
117
- between_times(Time.zone.now - 1.day, Time.zone.now, options)
118
- end
119
-
120
- def past_week(options={})
121
- between_times(Time.zone.now - 1.week, Time.zone.now, options)
122
- end
123
-
124
- def past_fortnight(options={})
125
- between_times(Time.zone.now - 2.weeks, Time.zone.now, options)
126
- end
127
-
128
- def past_month(options={})
129
- between_times(Time.zone.now - 1.month, Time.zone.now, options)
130
- end
131
-
132
- def past_year(options={})
133
- between_times(Time.zone.now - 1.year, Time.zone.now, options)
134
- end
135
-
136
- def next_day(options={})
137
- between_times(Time.zone.now, Time.zone.now + 1.day, options)
138
- end
139
-
140
- def next_week(options={})
141
- between_times(Time.zone.now, Time.zone.now + 1.week, options)
142
- end
143
-
144
- def next_fortnight(options={})
145
- between_times(Time.zone.now, Time.zone.now + 2.weeks, options)
146
- end
147
-
148
- def next_month(options={})
149
- between_times(Time.zone.now, Time.zone.now + 1.month, options)
150
- end
151
-
152
- def next_year(options={})
153
- between_times(Time.zone.now, Time.zone.now + 1.year, options)
154
- end
155
- end
156
- end
1
+ module ByStar
2
+
3
+ module Between
4
+
5
+ def between_times(*args)
6
+ options = args.extract_options!.symbolize_keys!
7
+
8
+ start_time, end_time = ByStar::Normalization.extract_range(args)
9
+ offset = options[:offset] || 0
10
+
11
+ if start_time.is_a?(Date)
12
+ start_time = ByStar::Normalization.apply_offset_start(start_time.in_time_zone, offset)
13
+ elsif start_time
14
+ start_time += offset.seconds
15
+ end
16
+
17
+ if end_time.is_a?(Date)
18
+ end_time = ByStar::Normalization.apply_offset_end(end_time.in_time_zone, offset)
19
+ elsif end_time
20
+ end_time += offset.seconds
21
+ end
22
+
23
+ start_field = by_star_start_field(options)
24
+ end_field = by_star_end_field(options)
25
+
26
+ scope = self
27
+ scope = if !start_time && !end_time
28
+ scope # do nothing
29
+ elsif !end_time
30
+ by_star_after_query(scope, start_field, start_time)
31
+ elsif !start_time
32
+ by_star_before_query(scope, start_field, end_time)
33
+ elsif start_field == end_field
34
+ by_star_point_query(scope, start_field, start_time, end_time)
35
+ elsif options[:strict]
36
+ by_star_span_strict_query(scope, start_field, end_field, start_time, end_time)
37
+ else
38
+ by_star_span_loose_query(scope, start_field, end_field, start_time, end_time, options)
39
+ end
40
+
41
+ scope = by_star_order(scope, options[:order]) if options[:order]
42
+ scope
43
+ end
44
+
45
+ def between_dates(*args)
46
+ options = args.extract_options!
47
+ start_date, end_date = ByStar::Normalization.extract_range(args)
48
+ start_date = ByStar::Normalization.date(start_date)
49
+ end_date = ByStar::Normalization.date(end_date)
50
+ between_times(start_date, end_date, options)
51
+ end
52
+
53
+ def at_time(*args)
54
+ with_by_star_options(*args) do |time, options|
55
+ start_field = by_star_start_field(options)
56
+ end_field = by_star_end_field(options)
57
+
58
+ scope = self
59
+ scope = if start_field == end_field
60
+ by_star_point_overlap_query(scope, start_field, time)
61
+ else
62
+ by_star_span_overlap_query(scope, start_field, end_field, time, options)
63
+ end
64
+ scope = by_star_order(scope, options[:order]) if options[:order]
65
+ scope
66
+ end
67
+ end
68
+
69
+ def by_day(*args)
70
+ with_by_star_options(*args) do |time, options|
71
+ date = ByStar::Normalization.date(time)
72
+ between_dates(date, date, options)
73
+ end
74
+ end
75
+
76
+ def by_week(*args)
77
+ with_by_star_options(*args) do |time, options|
78
+ date = ByStar::Normalization.week(time, options)
79
+ start_day = Array(options[:start_day])
80
+ between_dates(date.beginning_of_week(*start_day), date.end_of_week(*start_day), options)
81
+ end
82
+ end
83
+
84
+ def by_cweek(*args)
85
+ with_by_star_options(*args) do |time, options|
86
+ by_week(ByStar::Normalization.cweek(time, options), options)
87
+ end
88
+ end
89
+
90
+ def by_weekend(*args)
91
+ with_by_star_options(*args) do |time, options|
92
+ date = ByStar::Normalization.week(time, options)
93
+ between_dates(date.beginning_of_weekend, date.end_of_weekend, options)
94
+ end
95
+ end
96
+
97
+ def by_fortnight(*args)
98
+ with_by_star_options(*args) do |time, options|
99
+ date = ByStar::Normalization.fortnight(time, options)
100
+ between_dates(date.beginning_of_fortnight, date.end_of_fortnight, options)
101
+ end
102
+ end
103
+
104
+ def by_month(*args)
105
+ with_by_star_options(*args) do |time, options|
106
+ date = ByStar::Normalization.month(time, options)
107
+ between_dates(date.beginning_of_month, date.end_of_month, options)
108
+ end
109
+ end
110
+
111
+ def by_calendar_month(*args)
112
+ with_by_star_options(*args) do |time, options|
113
+ date = ByStar::Normalization.month(time, options)
114
+ start_day = Array(options[:start_day])
115
+ between_dates(date.beginning_of_calendar_month(*start_day), date.end_of_calendar_month(*start_day), options)
116
+ end
117
+ end
118
+
119
+ def by_quarter(*args)
120
+ with_by_star_options(*args) do |time, options|
121
+ date = ByStar::Normalization.quarter(time, options)
122
+ between_dates(date.beginning_of_quarter, date.end_of_quarter, options)
123
+ end
124
+ end
125
+
126
+ def by_year(*args)
127
+ with_by_star_options(*args) do |time, options|
128
+ date = ByStar::Normalization.year(time, options)
129
+ between_dates(date.beginning_of_year, date.to_date.end_of_year, options)
130
+ end
131
+ end
132
+
133
+ def today(options = {})
134
+ by_day(Date.current, options)
135
+ end
136
+
137
+ def yesterday(options = {})
138
+ by_day(Date.yesterday, options)
139
+ end
140
+
141
+ def tomorrow(options = {})
142
+ by_day(Date.tomorrow, options)
143
+ end
144
+
145
+ def past_day(options = {})
146
+ between_times(Time.current - 1.day, Time.current, options)
147
+ end
148
+
149
+ def past_week(options = {})
150
+ between_times(Time.current - 1.week, Time.current, options)
151
+ end
152
+
153
+ def past_fortnight(options = {})
154
+ between_times(Time.current - 2.weeks, Time.current, options)
155
+ end
156
+
157
+ def past_month(options = {})
158
+ between_times(Time.current - 1.month, Time.current, options)
159
+ end
160
+
161
+ def past_year(options = {})
162
+ between_times(Time.current - 1.year, Time.current, options)
163
+ end
164
+
165
+ def next_day(options = {})
166
+ between_times(Time.current, Time.current + 1.day, options)
167
+ end
168
+
169
+ def next_week(options = {})
170
+ between_times(Time.current, Time.current + 1.week, options)
171
+ end
172
+
173
+ def next_fortnight(options = {})
174
+ between_times(Time.current, Time.current + 2.weeks, options)
175
+ end
176
+
177
+ def next_month(options = {})
178
+ between_times(Time.current, Time.current + 1.month, options)
179
+ end
180
+
181
+ def next_year(options = {})
182
+ between_times(Time.current, Time.current + 1.year, options)
183
+ end
184
+ end
185
+ end