by_star 1.0.1 → 2.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.travis.yml +23 -0
- data/Gemfile +1 -7
- data/Gemfile.lock +77 -29
- data/README.markdown +28 -172
- data/by_star.gemspec +6 -0
- data/lib/by_star.rb +48 -28
- data/lib/by_star/by_day.rb +30 -0
- data/lib/by_star/by_direction.rb +52 -0
- data/lib/by_star/by_fortnight.rb +54 -0
- data/lib/by_star/by_month.rb +35 -0
- data/lib/by_star/by_week.rb +30 -0
- data/lib/by_star/by_weekend.rb +17 -0
- data/lib/by_star/by_year.rb +60 -0
- data/lib/by_star/instance_methods.rb +13 -0
- data/lib/by_star/time_ext.rb +2 -1
- data/lib/by_star/version.rb +1 -1
- data/spec/by_star/by_day_spec.rb +52 -0
- data/spec/by_star/by_direction_spec.rb +82 -0
- data/spec/by_star/by_fortnight_spec.rb +46 -0
- data/spec/by_star/by_month_spec.rb +60 -0
- data/spec/by_star/by_week_spec.rb +39 -0
- data/spec/by_star/by_weekend_spec.rb +12 -0
- data/spec/by_star/by_year_spec.rb +57 -0
- data/spec/database.yml +13 -7
- data/spec/fixtures/models.rb +7 -60
- data/spec/spec_helper.rb +13 -7
- data/spec/time_ext_spec.rb +10 -0
- metadata +114 -59
- data/init.rb +0 -2
- data/lib/by_star/calculations.rb +0 -23
- data/lib/by_star/calculations/count.rb +0 -20
- data/lib/by_star/calculations/sum.rb +0 -25
- data/lib/by_star/neighbours.rb +0 -15
- data/lib/by_star/range_calculations.rb +0 -23
- data/lib/by_star/shared.rb +0 -18
- data/lib/by_star/vanilla.rb +0 -276
- data/spec/by_star_spec.rb +0 -722
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe Time do
|
3
|
+
it "should work out the beginning of a weekend (Friday 3pm)" do
|
4
|
+
Time.now.beginning_of_weekend.strftime("%A %I:%M%p").should eql("Friday 03:00PM")
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should work out the end of a weekend (Monday 3am)" do
|
8
|
+
Time.now.end_of_weekend.strftime("%A %I:%M%p").should eql("Monday 03:00AM")
|
9
|
+
end
|
10
|
+
end
|
metadata
CHANGED
@@ -1,61 +1,113 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: by_star
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.0.0.beta1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Ryan Bigg
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2012-02-20 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: bundler
|
17
|
-
|
18
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70234733397300 !ruby/object:Gem::Requirement
|
19
17
|
none: false
|
20
|
-
requirements:
|
21
|
-
- -
|
22
|
-
- !ruby/object:Gem::Version
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
23
21
|
version: 1.0.0
|
24
22
|
type: :development
|
25
|
-
version_requirements: *id001
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: activerecord
|
28
23
|
prerelease: false
|
29
|
-
|
24
|
+
version_requirements: *70234733397300
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: sqlite3
|
27
|
+
requirement: &70234733396920 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70234733396920
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: pg
|
38
|
+
requirement: &70234733396460 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70234733396460
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mysql2
|
49
|
+
requirement: &70234733396040 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70234733396040
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rspec-rails
|
60
|
+
requirement: &70234733395540 !ruby/object:Gem::Requirement
|
30
61
|
none: false
|
31
|
-
requirements:
|
32
|
-
- -
|
33
|
-
- !ruby/object:Gem::Version
|
62
|
+
requirements:
|
63
|
+
- - ~>
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '2.8'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70234733395540
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: timecop
|
71
|
+
requirement: &70234733395040 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.3'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *70234733395040
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: activerecord
|
82
|
+
requirement: &70234733394580 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
34
87
|
version: 2.0.0
|
35
88
|
type: :runtime
|
36
|
-
version_requirements: *id002
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: chronic
|
39
89
|
prerelease: false
|
40
|
-
|
90
|
+
version_requirements: *70234733394580
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: chronic
|
93
|
+
requirement: &70234733394200 !ruby/object:Gem::Requirement
|
41
94
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version:
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
46
99
|
type: :runtime
|
47
|
-
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *70234733394200
|
48
102
|
description: ActiveRecord extension for easier date scopes and time ranges
|
49
|
-
email:
|
103
|
+
email:
|
50
104
|
- radarlistener@gmail.com
|
51
105
|
executables: []
|
52
|
-
|
53
106
|
extensions: []
|
54
|
-
|
55
107
|
extra_rdoc_files: []
|
56
|
-
|
57
|
-
files:
|
108
|
+
files:
|
58
109
|
- .gitignore
|
110
|
+
- .travis.yml
|
59
111
|
- Gemfile
|
60
112
|
- Gemfile.lock
|
61
113
|
- MIT-LICENSE
|
@@ -63,49 +115,52 @@ files:
|
|
63
115
|
- Rakefile
|
64
116
|
- by_star.gemspec
|
65
117
|
- cleaner.rb
|
66
|
-
- init.rb
|
67
118
|
- lib/by_star.rb
|
68
|
-
- lib/by_star/
|
69
|
-
- lib/by_star/
|
70
|
-
- lib/by_star/
|
71
|
-
- lib/by_star/
|
72
|
-
- lib/by_star/
|
73
|
-
- lib/by_star/
|
119
|
+
- lib/by_star/by_day.rb
|
120
|
+
- lib/by_star/by_direction.rb
|
121
|
+
- lib/by_star/by_fortnight.rb
|
122
|
+
- lib/by_star/by_month.rb
|
123
|
+
- lib/by_star/by_week.rb
|
124
|
+
- lib/by_star/by_weekend.rb
|
125
|
+
- lib/by_star/by_year.rb
|
126
|
+
- lib/by_star/instance_methods.rb
|
74
127
|
- lib/by_star/time_ext.rb
|
75
|
-
- lib/by_star/vanilla.rb
|
76
128
|
- lib/by_star/version.rb
|
77
|
-
- spec/
|
129
|
+
- spec/by_star/by_day_spec.rb
|
130
|
+
- spec/by_star/by_direction_spec.rb
|
131
|
+
- spec/by_star/by_fortnight_spec.rb
|
132
|
+
- spec/by_star/by_month_spec.rb
|
133
|
+
- spec/by_star/by_week_spec.rb
|
134
|
+
- spec/by_star/by_weekend_spec.rb
|
135
|
+
- spec/by_star/by_year_spec.rb
|
78
136
|
- spec/database.yml
|
79
137
|
- spec/fixtures/models.rb
|
80
138
|
- spec/fixtures/schema.rb
|
81
139
|
- spec/spec_helper.rb
|
140
|
+
- spec/time_ext_spec.rb
|
82
141
|
- tmp/.gitignore
|
83
142
|
homepage: http://rubygems.org/gems/by_star
|
84
143
|
licenses: []
|
85
|
-
|
86
144
|
post_install_message:
|
87
145
|
rdoc_options: []
|
88
|
-
|
89
|
-
require_paths:
|
146
|
+
require_paths:
|
90
147
|
- lib
|
91
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
149
|
none: false
|
93
|
-
requirements:
|
94
|
-
- -
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version:
|
97
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ! '>='
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
155
|
none: false
|
99
|
-
requirements:
|
100
|
-
- -
|
101
|
-
- !ruby/object:Gem::Version
|
156
|
+
requirements:
|
157
|
+
- - ! '>='
|
158
|
+
- !ruby/object:Gem::Version
|
102
159
|
version: 1.3.6
|
103
160
|
requirements: []
|
104
|
-
|
105
161
|
rubyforge_project: by_star
|
106
|
-
rubygems_version: 1.8.
|
162
|
+
rubygems_version: 1.8.15
|
107
163
|
signing_key:
|
108
164
|
specification_version: 3
|
109
165
|
summary: ActiveRecord extension for easier date scopes and time ranges
|
110
166
|
test_files: []
|
111
|
-
|
data/init.rb
DELETED
data/lib/by_star/calculations.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module ByStar
|
2
|
-
module Calculations
|
3
|
-
include Count
|
4
|
-
include Sum
|
5
|
-
|
6
|
-
private
|
7
|
-
def work_out_month(time, year=Time.zone.now.year)
|
8
|
-
year ||= Time.zone.now.year
|
9
|
-
# Work out what actual month is.
|
10
|
-
month = if time.is_a?(Numeric) && (1..12).include?(time)
|
11
|
-
time
|
12
|
-
elsif valid_time_or_date?(time)
|
13
|
-
year = time.year
|
14
|
-
time.month
|
15
|
-
elsif time.is_a?(String) && Date::MONTHNAMES.include?(time)
|
16
|
-
Date::MONTHNAMES.index(time)
|
17
|
-
else
|
18
|
-
raise ParseError, "Value is not an integer (between 1 and 12), time object or string (make sure you typed the name right)."
|
19
|
-
end
|
20
|
-
[year, month]
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module ByStar
|
2
|
-
module Calculations
|
3
|
-
module Count
|
4
|
-
def count_by_year(field=nil, year=Time.zone.now.year, options={}, &block)
|
5
|
-
db_field = options.delete(:field)
|
6
|
-
scoped_by(block) do
|
7
|
-
count(field, { :conditions => conditions_for_range(start_of_year(year), end_of_year(year), db_field) }.reverse_merge!(options))
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def count_by_month(field=nil, month=Time.now.month, options={}, &block)
|
12
|
-
db_field = options.delete(:field)
|
13
|
-
year, month = work_out_month(month, options.delete(:year))
|
14
|
-
scoped_by(block) do
|
15
|
-
count(field, { :conditions => conditions_for_range(start_of_month(month, year), end_of_month(month, year), db_field) }.reverse_merge!(options))
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
module ByStar
|
2
|
-
module Calculations
|
3
|
-
module Sum
|
4
|
-
def sum_by_year(field, year=Time.zone.now.year, options={}, &block)
|
5
|
-
scoped_by(block) do
|
6
|
-
sum(field, { :conditions => conditions_for_range(start_of_year(year), end_of_year(year), options.delete(:field)) }.reverse_merge!(options))
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
def sum_by_month(field, month=Time.zone.now.month, options={}, &block)
|
11
|
-
year, month = work_out_month(month, options.delete(:year))
|
12
|
-
scoped_by(block) do
|
13
|
-
sum(field, { :conditions => conditions_for_range(start_of_month(month, year), end_of_month(month, year), options.delete(:field)) }.reverse_merge!(options))
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def sum_by_day(field, day=Time.zone.now, options={}, &block)
|
18
|
-
scoped_by(block) do
|
19
|
-
day = parse(day)
|
20
|
-
sum(field, { :conditions => conditions_for_range(day.beginning_of_day, day.end_of_day, options.delete(:field)) }.reverse_merge!(options))
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/by_star/neighbours.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
module ByStar
|
2
|
-
module Neighbours
|
3
|
-
# Find the previous record to this.
|
4
|
-
def previous(field=nil)
|
5
|
-
field = field || self.class.by_star_field
|
6
|
-
self.class.past(self.send(field.to_s.split(".").last)) { { :order => "#{field} DESC" }}.first
|
7
|
-
end
|
8
|
-
|
9
|
-
# Find the next record to this.
|
10
|
-
def next(field=nil)
|
11
|
-
field = field || self.class.by_star_field
|
12
|
-
self.class.future(self.send(field.to_s.split(".").last)) { { :order => "#{field} ASC" }}.first
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
module ByStar
|
2
|
-
module RangeCalculations
|
3
|
-
|
4
|
-
private
|
5
|
-
|
6
|
-
def start_of_year(year=Time.zone.now.year)
|
7
|
-
Time.utc(year, 1, 1)
|
8
|
-
end
|
9
|
-
|
10
|
-
def end_of_year(year=Time.zone.now.year)
|
11
|
-
start_of_year(year).end_of_year
|
12
|
-
end
|
13
|
-
|
14
|
-
def start_of_month(month, year=Timeow.year)
|
15
|
-
Time.utc(year, month, 1)
|
16
|
-
end
|
17
|
-
|
18
|
-
def end_of_month(month, year=Time.now.year)
|
19
|
-
start_of_month(month, year).end_of_month
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
end
|
data/lib/by_star/shared.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Shared
|
2
|
-
def conditions_for_range(start_time, end_time, field=nil)
|
3
|
-
field = "#{table_name}.#{field}" if field
|
4
|
-
field ||= by_star_field
|
5
|
-
["#{field} >= ? AND #{field} <= ?", start_time.utc, end_time.utc]
|
6
|
-
end
|
7
|
-
|
8
|
-
private
|
9
|
-
def scoped_by(options=nil, &block)
|
10
|
-
if options && scope = options.call
|
11
|
-
with_scope(:find => scope) do
|
12
|
-
block.call
|
13
|
-
end
|
14
|
-
else
|
15
|
-
block.call
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/lib/by_star/vanilla.rb
DELETED
@@ -1,276 +0,0 @@
|
|
1
|
-
module ByStar
|
2
|
-
module Vanilla
|
3
|
-
# Examples:
|
4
|
-
# by_year(2010)
|
5
|
-
# # 2-digit year:
|
6
|
-
# by_year(10)
|
7
|
-
# # Time or Date object:
|
8
|
-
# by_year(time)
|
9
|
-
# # String:
|
10
|
-
# by_year("2010")
|
11
|
-
def by_year(time=Time.zone.now.year, options={}, &block)
|
12
|
-
year = work_out_year(time)
|
13
|
-
start_time = start_of_year(year)
|
14
|
-
end_time = start_time.end_of_year
|
15
|
-
by_star(start_time, end_time, options, &block)
|
16
|
-
rescue ArgumentError
|
17
|
-
raise ParseError, "Invalid arguments detected, year may possibly be outside of valid range (1902-2039). This is no longer a problem on Ruby versions >= 1.8.7, so we recommend you upgrade to at least 1.8.7."
|
18
|
-
end
|
19
|
-
|
20
|
-
# Examples:
|
21
|
-
# by_month(1)
|
22
|
-
# by_month("January")
|
23
|
-
# by_month("January", :year => 2008)
|
24
|
-
# by_month(time)
|
25
|
-
def by_month(time=Time.zone.now.month, options={}, &block)
|
26
|
-
time = Time.zone.now.month if time.nil?
|
27
|
-
year, month = work_out_month(time, options.delete(:year))
|
28
|
-
|
29
|
-
start_time = start_of_month(month, year)
|
30
|
-
end_time = start_time.end_of_month
|
31
|
-
|
32
|
-
by_star(start_time, end_time, options, &block)
|
33
|
-
end
|
34
|
-
|
35
|
-
# Examples:
|
36
|
-
# # 18th fortnight of 2004
|
37
|
-
# Post.by_fortnight(18, :year => 2004)
|
38
|
-
def by_fortnight(time=Time.zone.now, options = {}, &block)
|
39
|
-
time = parse(time)
|
40
|
-
|
41
|
-
# If options[:year] is passed in, use that year regardless.
|
42
|
-
year = work_out_year(options[:year]) if options[:year]
|
43
|
-
# If the first argument is a date or time, ask it for the year
|
44
|
-
year ||= time.year unless time.is_a?(Numeric)
|
45
|
-
# If the first argument is a fixnum, assume this year.
|
46
|
-
year ||= Time.zone.now.year
|
47
|
-
|
48
|
-
# Dodgy!
|
49
|
-
# Surely there's a method in Rails to do this.
|
50
|
-
start_time = if valid_time_or_date?(time)
|
51
|
-
time.beginning_of_year + (time.strftime("%U").to_i).weeks
|
52
|
-
elsif time.is_a?(Numeric) && time <= 26
|
53
|
-
Time.utc(year, 1, 1) + ((time.to_i) * 2).weeks
|
54
|
-
else
|
55
|
-
raise ParseError, "by_fortnight takes only a Time or Date object, a Fixnum (less than or equal to 26) or a Chronicable string."
|
56
|
-
end
|
57
|
-
start_time = start_time.beginning_of_week
|
58
|
-
end_time = start_time + 2.weeks
|
59
|
-
by_star(start_time, end_time, options, &block)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Examples:
|
63
|
-
# # 36th week
|
64
|
-
# Post.by_week(36)
|
65
|
-
# Post.by_week(36.54)
|
66
|
-
# Post.by_week(36, :year => 2004)
|
67
|
-
# Post.by_week(<Time object>)
|
68
|
-
# Post.by_week(<Date object>)
|
69
|
-
# Post.by_week("next tuesday")
|
70
|
-
def by_week(time=Time.zone.now, options = {}, &block)
|
71
|
-
time = parse(time)
|
72
|
-
|
73
|
-
# If options[:year] is passed in, use that year regardless.
|
74
|
-
year = work_out_year(options.delete(:year)) if options[:year]
|
75
|
-
# If the first argument is a date or time, ask it for the year
|
76
|
-
year ||= time.year unless time.is_a?(Numeric)
|
77
|
-
# If the first argument is a fixnum, assume this year.
|
78
|
-
year ||= Time.zone.now.year
|
79
|
-
|
80
|
-
# Dodgy!
|
81
|
-
# Surely there's a method in Rails to do this.
|
82
|
-
start_time = if valid_time_or_date?(time)
|
83
|
-
weeks = time.strftime("%U").to_i
|
84
|
-
Time.zone.now.beginning_of_year
|
85
|
-
elsif time.is_a?(Numeric) && time < 53
|
86
|
-
weeks = time.to_i
|
87
|
-
Time.utc(year, 1, 1)
|
88
|
-
else
|
89
|
-
raise ParseError, "by_week takes only a Time or Date object, a Fixnum (less than or equal to 53) or a Chronicable string."
|
90
|
-
end
|
91
|
-
# Make the start of the week predictably Sunday.
|
92
|
-
start_time.strftime("%w").to_i != 0 ? start_time - (7 - start_time.strftime("%w").to_i).days : start_time
|
93
|
-
start_time += weeks.weeks
|
94
|
-
end_time = start_time + 1.week
|
95
|
-
by_star(start_time, end_time, options, &block)
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
# Examples:
|
100
|
-
# Post.by_weekend
|
101
|
-
# Post.by_weekend(Time.now + 5.days)
|
102
|
-
# Post.by_weekend(Date.today + 5)
|
103
|
-
# Post.by_weekend("next tuesday")
|
104
|
-
def by_weekend(time=Time.now, options = {}, &block)
|
105
|
-
time = parse(time)
|
106
|
-
start_time = time.beginning_of_weekend
|
107
|
-
end_time = (start_time + 1.day).end_of_day
|
108
|
-
by_star(start_time, end_time, options, &block)
|
109
|
-
end
|
110
|
-
|
111
|
-
|
112
|
-
# Examples:
|
113
|
-
# Post.by_current_weekend
|
114
|
-
def by_current_weekend(options = {}, &block)
|
115
|
-
time = Time.zone.now
|
116
|
-
# Friday, 3pm
|
117
|
-
start_time = time.beginning_of_weekend
|
118
|
-
# Monday, 3am
|
119
|
-
end_time = time.end_of_weekend
|
120
|
-
by_star(start_time, end_time, options, &block)
|
121
|
-
end
|
122
|
-
|
123
|
-
# Examples:
|
124
|
-
# Post.by_current_work_week
|
125
|
-
def by_current_work_week(options = {}, &block)
|
126
|
-
time = Time.zone.now
|
127
|
-
# Monday, 3am
|
128
|
-
time = time + 1.week if time.wday == 6 || time.wday == 0
|
129
|
-
start_time = time.beginning_of_week + 3.hours
|
130
|
-
# Friday, 3pm
|
131
|
-
end_time = time.beginning_of_weekend
|
132
|
-
by_star(start_time, end_time, options, &block)
|
133
|
-
end
|
134
|
-
|
135
|
-
|
136
|
-
# Examples:
|
137
|
-
# Post.by_day
|
138
|
-
# Post.by_day(Time.yesterday)
|
139
|
-
# Post.by_day("next tuesday")
|
140
|
-
def by_day(time = Time.zone.now, options = {}, &block)
|
141
|
-
time = parse(time)
|
142
|
-
by_star(time.beginning_of_day, time.end_of_day, options, &block)
|
143
|
-
end
|
144
|
-
alias_method :today, :by_day
|
145
|
-
|
146
|
-
# Examples:
|
147
|
-
# Post.yesterday
|
148
|
-
# # 2 days ago:
|
149
|
-
# Post.yesterday(Time.yesterday)
|
150
|
-
# # day before next tuesday
|
151
|
-
# Post.yesterday("next tuesday")
|
152
|
-
def yesterday(time = Time.zone.now, options = {}, &block)
|
153
|
-
time = parse(time)
|
154
|
-
by_day(time.advance(:days => -1), options, &block)
|
155
|
-
end
|
156
|
-
|
157
|
-
# Examples:
|
158
|
-
# Post.tomorrow
|
159
|
-
# # 2 days from now:
|
160
|
-
# Post.tomorrow(Time.tomorrow)
|
161
|
-
# # day after next tuesday
|
162
|
-
# Post.tomorrow("next tuesday")
|
163
|
-
def tomorrow(time = Time.zone.now, options = {}, &block)
|
164
|
-
time = parse(time)
|
165
|
-
by_day(time.advance(:days => 1), options, &block)
|
166
|
-
end
|
167
|
-
|
168
|
-
# Scopes to records older than current or given time
|
169
|
-
# Post.past
|
170
|
-
# Post.past()
|
171
|
-
def past(time = Time.zone.now, options = {}, &block)
|
172
|
-
time = parse(time)
|
173
|
-
by_direction("<", time, options, &block)
|
174
|
-
end
|
175
|
-
|
176
|
-
# Scopes to records newer than current or given time
|
177
|
-
def future(time = Time.zone.now, options = {}, &block)
|
178
|
-
time = parse(time)
|
179
|
-
by_direction(">", time, options, &block)
|
180
|
-
end
|
181
|
-
|
182
|
-
private
|
183
|
-
|
184
|
-
def by_direction(condition, time, options = {}, &block)
|
185
|
-
field = options.delete(:field) || by_star_field
|
186
|
-
ensure_valid_options(options)
|
187
|
-
result = scoped({ :conditions => ["#{field} #{condition} ?", time.utc] }.merge(options))
|
188
|
-
result = result.scoped(block.call) if block_given?
|
189
|
-
result
|
190
|
-
end
|
191
|
-
|
192
|
-
# scopes results between start_time and end_time
|
193
|
-
def by_star(start_time, end_time, options = {}, &block)
|
194
|
-
start_time = parse(start_time)
|
195
|
-
end_time = parse(end_time)
|
196
|
-
|
197
|
-
|
198
|
-
raise ParseError, "End time is before start time, searching like this will return no results." if end_time < start_time
|
199
|
-
field = options.delete(:field)
|
200
|
-
ensure_valid_options(options)
|
201
|
-
|
202
|
-
scoping = { :conditions => conditions_for_range(start_time, end_time, field) }.merge(options)
|
203
|
-
result = scoped(scoping)
|
204
|
-
result = result.scoped(block.call) if block_given?
|
205
|
-
result
|
206
|
-
end
|
207
|
-
|
208
|
-
def ensure_valid_options(options)
|
209
|
-
if respond_to?(:validate_find_options)
|
210
|
-
validate_find_options(options)
|
211
|
-
else
|
212
|
-
options.assert_valid_keys(ActiveRecord::SpawnMethods::VALID_FIND_OPTIONS)
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
alias :between :by_star
|
217
|
-
public :between
|
218
|
-
|
219
|
-
# This will work for the next 30 years (written in 2009)
|
220
|
-
def work_out_year(value)
|
221
|
-
case value
|
222
|
-
when 0..39
|
223
|
-
2000 + value
|
224
|
-
when 40..99
|
225
|
-
1900 + value
|
226
|
-
when nil
|
227
|
-
Time.zone.now.year
|
228
|
-
else
|
229
|
-
# We may be passed something that's not a straight out integer
|
230
|
-
# These things include: BigDecimals, Floats and Strings.
|
231
|
-
value.to_i
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
# Checks if the object is a Time, Date or TimeWithZone object.
|
236
|
-
def valid_time_or_date?(value)
|
237
|
-
value.is_a?(Time) || value.is_a?(Date) || value.is_a?(ActiveSupport::TimeWithZone)
|
238
|
-
end
|
239
|
-
|
240
|
-
def parse(object)
|
241
|
-
object = case object.class.to_s
|
242
|
-
when "NilClass"
|
243
|
-
o = Time.zone.now
|
244
|
-
when "String"
|
245
|
-
o = object
|
246
|
-
Chronic.parse(object, :now => Time.zone.now)
|
247
|
-
when "Date"
|
248
|
-
object.to_time(:utc)
|
249
|
-
else
|
250
|
-
object
|
251
|
-
end
|
252
|
-
raise ParseError, "Chronic couldn't work out #{o.inspect}; please be more precise." if object.nil?
|
253
|
-
object
|
254
|
-
end
|
255
|
-
|
256
|
-
def method_missing(method, *args)
|
257
|
-
if method.to_s =~ /^(as_of|up_to)_(.+)$/
|
258
|
-
method = $1
|
259
|
-
expr = $2.humanize
|
260
|
-
unless time = parse(expr)
|
261
|
-
raise ParseError, "Chronic couldn't work out #{expr.inspect}; please be more precise."
|
262
|
-
end
|
263
|
-
|
264
|
-
reference = args.first || Time.now
|
265
|
-
|
266
|
-
if "as_of" == method
|
267
|
-
between(time, reference)
|
268
|
-
else
|
269
|
-
between(reference, time)
|
270
|
-
end
|
271
|
-
else
|
272
|
-
super
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
end
|