ruby-sun-times 0.1.4 → 0.1.5
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 +7 -0
- data/README.md +12 -2
- data/lib/sun_times.rb +86 -29
- data/lib/sun_times/version.rb +2 -2
- data/spec/unit/ruby_sun_times_spec.rb +56 -42
- metadata +69 -47
- checksums.yaml +0 -7
data/.travis.yml
ADDED
data/README.md
CHANGED
@@ -1,6 +1,16 @@
|
|
1
|
-
#
|
1
|
+
# ruby-sun-times [][Continuous Integration]
|
2
2
|
|
3
|
-
Calculates sunrise and sunset times
|
3
|
+
*Calculates sunrise and sunset times*
|
4
|
+
|
5
|
+
* [Source Code]
|
6
|
+
* [API documentation]
|
7
|
+
* [Rubygem]
|
8
|
+
* [Continuous Integration]
|
9
|
+
|
10
|
+
[Source Code]: https://github.com/joeyates/ruby-sun-times "Source code at GitHub"
|
11
|
+
[API documentation]: http://rubydoc.info/gems/ruby-sun-times/frames "RDoc API Documentation at Rubydoc.info"
|
12
|
+
[Rubygem]: http://rubygems.org/gems/ruby-sun-times "Ruby gem at rubygems.org"
|
13
|
+
[Continuous Integration]: http://travis-ci.org/joeyates/ruby-sun-times "Build status by Travis-CI"
|
4
14
|
|
5
15
|
An implementation of the algorithm descibed at http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
|
6
16
|
|
data/lib/sun_times.rb
CHANGED
@@ -25,50 +25,75 @@
|
|
25
25
|
|
26
26
|
require 'date'
|
27
27
|
|
28
|
-
|
28
|
+
class SunTimes
|
29
29
|
DEFAULT_ZENITH = 90.83333
|
30
30
|
KNOWN_EVENTS = [:rise, :set]
|
31
31
|
DEGREES_PER_HOUR = 360.0 / 24.0
|
32
32
|
|
33
|
-
|
33
|
+
attr_reader :options
|
34
|
+
|
35
|
+
# Deprecated: use SunTimes.new.rise(...)
|
34
36
|
def self.rise(date, latitude, longitude, options = {})
|
35
|
-
calculate(:rise, date, latitude, longitude, options)
|
37
|
+
new(options).calculate(:rise, date, latitude, longitude, options)
|
36
38
|
end
|
37
39
|
|
38
|
-
#
|
40
|
+
# Deprecated: use SunTimes.new.set(...)
|
39
41
|
def self.set(date, latitude, longitude, options = {})
|
40
|
-
calculate(:set, date, latitude, longitude, options)
|
42
|
+
new(options).calculate(:set, date, latitude, longitude, options)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Deprecated: use SunTimes.new.rise/set(...)
|
46
|
+
def self.calculate(event, date, latitude, longitude, options = {})
|
47
|
+
new(options).calculate(event, date, latitude, longitude)
|
41
48
|
end
|
42
49
|
|
43
|
-
# Calculates the sunrise or sunset time for a specific date and location
|
44
|
-
#
|
45
|
-
# ==== Parameters
|
46
|
-
# * +event+ - One of :rise, :set.
|
47
|
-
# * +date+ - An object that responds to :to_datetime.
|
48
|
-
# * +latitude+ - The latitude of the location in degrees.
|
49
|
-
# * +longitude+ - The longitude of the location in degrees.
|
50
50
|
# * +options+ -
|
51
51
|
# * <tt>:never_rises_result</tt> - the value to be returned if the sun never rises on the supplied date,
|
52
52
|
# * <tt>:never_sets_result</tt> - the value to be returned if the sun never sets on the supplied date,
|
53
53
|
# * <tt>:zenith</tt> - default 90.83333
|
54
|
-
|
55
|
-
|
56
|
-
# SunTimes.calculate(:rise, Date.new(2010, 3, 8), 43.779, 11.432)
|
57
|
-
# > Mon Mar 08 05:39:53 UTC 2010
|
58
|
-
def self.calculate(event, date, latitude, longitude, options = {})
|
59
|
-
options = {
|
54
|
+
def initialize(options = {})
|
55
|
+
@options = {
|
60
56
|
:never_sets_result => nil,
|
61
57
|
:never_rises_result => nil,
|
62
58
|
:zenith => DEFAULT_ZENITH,
|
63
59
|
}.merge(options)
|
64
|
-
|
65
|
-
|
60
|
+
end
|
61
|
+
|
62
|
+
# Calculates the sunrise time for a specific date and location
|
63
|
+
#
|
64
|
+
# ==== Parameters
|
65
|
+
# * +date+ - An object that responds to :to_datetime.
|
66
|
+
# * +latitude+ - The latitude of the location in degrees.
|
67
|
+
# * +longitude+ - The longitude of the location in degrees.
|
68
|
+
#
|
69
|
+
# ==== Example
|
70
|
+
# SunTimes.new.rise(Date.new(2010, 3, 8), 43.779, 11.432)
|
71
|
+
# > Mon Mar 08 05:39:53 UTC 2010
|
72
|
+
def rise(date, latitude, longitude)
|
73
|
+
calculate(:rise, date, latitude, longitude)
|
74
|
+
end
|
75
|
+
|
76
|
+
# calculates sunset, see #rise for parameters
|
77
|
+
def set(date, latitude, longitude)
|
78
|
+
calculate(:set, date, latitude, longitude)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def calculate(event, date, latitude, longitude)
|
84
|
+
datetime = to_datetime(date)
|
85
|
+
raise "Unknown event '#{event}'" unless KNOWN_EVENTS.include?(event)
|
66
86
|
|
67
87
|
# lngHour
|
68
88
|
longitude_hour = longitude / DEGREES_PER_HOUR
|
69
89
|
|
70
90
|
# t
|
71
|
-
base_time =
|
91
|
+
base_time =
|
92
|
+
if event == :rise
|
93
|
+
6.0
|
94
|
+
else
|
95
|
+
18.0
|
96
|
+
end
|
72
97
|
approximate_time = datetime.yday + (base_time - longitude_hour) / 24.0
|
73
98
|
|
74
99
|
# M
|
@@ -128,12 +153,12 @@ module SunTimes
|
|
128
153
|
offset_hours = datetime.offset * 24.0
|
129
154
|
|
130
155
|
if gmt_hours + offset_hours < 0
|
131
|
-
next_day = datetime
|
132
|
-
return calculate(event, next_day.new_offset, latitude, longitude
|
156
|
+
next_day = next_day(datetime)
|
157
|
+
return calculate(event, next_day.new_offset, latitude, longitude)
|
133
158
|
end
|
134
159
|
if gmt_hours + offset_hours > 24
|
135
|
-
previous_day = datetime
|
136
|
-
return calculate(event, previous_day.new_offset, latitude, longitude
|
160
|
+
previous_day = prev_day(datetime)
|
161
|
+
return calculate(event, previous_day.new_offset, latitude, longitude)
|
137
162
|
end
|
138
163
|
|
139
164
|
hour = gmt_hours.floor
|
@@ -144,17 +169,49 @@ module SunTimes
|
|
144
169
|
Time.gm(datetime.year, datetime.month, datetime.day, hour, minute, seconds)
|
145
170
|
end
|
146
171
|
|
147
|
-
|
172
|
+
############################
|
173
|
+
# ruby 1.8 compatibility
|
174
|
+
|
175
|
+
def to_datetime(date)
|
176
|
+
if date.respond_to?(:to_datetime)
|
177
|
+
date.to_datetime
|
178
|
+
else
|
179
|
+
values = [
|
180
|
+
date.year,
|
181
|
+
date.month,
|
182
|
+
date.day,
|
183
|
+
]
|
184
|
+
[:hour, :minute, :second, :zone].each do |m|
|
185
|
+
values <<
|
186
|
+
if date.respond_to?(m)
|
187
|
+
date.send(m)
|
188
|
+
else
|
189
|
+
0
|
190
|
+
end
|
191
|
+
end
|
192
|
+
DateTime.new(*values)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
def prev_day(datetime)
|
197
|
+
datetime - 1
|
198
|
+
end
|
199
|
+
|
200
|
+
def next_day(datetime)
|
201
|
+
datetime + 1
|
202
|
+
end
|
203
|
+
|
204
|
+
############################
|
148
205
|
|
149
|
-
def
|
206
|
+
def degrees_to_radians(d)
|
150
207
|
d.to_f / 360.0 * 2.0 * Math::PI
|
151
208
|
end
|
152
209
|
|
153
|
-
def
|
210
|
+
def radians_to_degrees(r)
|
154
211
|
r.to_f * 360.0 / (2.0 * Math::PI)
|
155
212
|
end
|
156
213
|
|
157
|
-
def
|
214
|
+
def coerce_degrees(d)
|
158
215
|
if d < 0
|
159
216
|
d += 360
|
160
217
|
return coerce_degrees(d)
|
data/lib/sun_times/version.rb
CHANGED
@@ -1,101 +1,115 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SunTimes do
|
4
|
+
let(:options) { {} }
|
4
5
|
let(:day) { Date.new(2010, 3, 8) }
|
5
6
|
let(:latitude) { 43.779 }
|
6
7
|
let(:longitude) { 11.432 }
|
7
|
-
let(:rise) { Time.gm(2010, 3, 8, 5, 39, 53) }
|
8
|
-
let(:set) { Time.gm(2010, 3, 8, 17, 11, 16) }
|
9
8
|
let(:midsummer) { Date.new(2010, 6, 21) }
|
10
9
|
let(:midwinter) { Date.new(2010, 12, 21) }
|
11
10
|
let(:north_cape_latitude) { 71.170219 }
|
12
11
|
let(:north_cape_longitude) { 25.785556 }
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
13
|
+
subject { described_class.new(options) }
|
14
|
+
|
15
|
+
shared_examples_for 'never sets and never rises options' do |method|
|
16
|
+
context ':never_rises_result' do
|
17
|
+
let(:options) do
|
18
|
+
{
|
19
|
+
:never_rises_result => :never_rises,
|
20
|
+
:never_sets_result => :never_sets,
|
21
|
+
}
|
19
22
|
end
|
20
|
-
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
context 'never rises' do
|
25
|
+
it 'uses the supplied value' do
|
26
|
+
result = subject.send(method, midwinter, north_cape_latitude, north_cape_longitude)
|
27
|
+
expect(result).to eq(:never_rises)
|
28
|
+
end
|
26
29
|
end
|
27
|
-
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
context 'never sets' do
|
32
|
+
it 'uses the supplied value' do
|
33
|
+
result = subject.send(method, midsummer, north_cape_latitude, north_cape_longitude)
|
34
|
+
expect(result).to eq(:never_sets)
|
35
|
+
end
|
34
36
|
end
|
35
37
|
end
|
38
|
+
end
|
36
39
|
|
40
|
+
shared_examples_for 'timezones' do |method|
|
37
41
|
context 'with timezone' do
|
38
42
|
let(:zone) { Rational(-8, 24) }
|
39
43
|
let(:day_with_zone) { DateTime.new(2011, 12, 13, 0, 0, 0, zone) }
|
40
44
|
|
41
45
|
it 'calculates according to the supplied value' do
|
42
|
-
set =
|
46
|
+
set = subject.send(method, day_with_zone, 45.52, -122.681944)
|
43
47
|
result_datetime = DateTime.new(set.year, set.month, set.day, set.hour, set.min, set.sec, 0)
|
44
48
|
|
45
49
|
expect(result_datetime).to be > day_with_zone
|
46
50
|
expect(result_datetime).to be <= day_with_zone + 1
|
47
51
|
end
|
48
52
|
end
|
53
|
+
end
|
49
54
|
|
55
|
+
shared_examples_for 'no event' do |method|
|
50
56
|
context 'midnight sun' do
|
51
|
-
it '
|
52
|
-
result =
|
57
|
+
it 'is nil' do
|
58
|
+
result = subject.send(method, midsummer, north_cape_latitude, north_cape_longitude)
|
53
59
|
expect(result).to be_nil
|
54
60
|
end
|
61
|
+
end
|
55
62
|
|
56
|
-
|
57
|
-
|
63
|
+
context 'continuous night' do
|
64
|
+
it 'is nil' do
|
65
|
+
result = subject.send(method, midwinter, north_cape_latitude, north_cape_longitude)
|
58
66
|
expect(result).to be_nil
|
59
67
|
end
|
60
68
|
end
|
69
|
+
end
|
61
70
|
|
71
|
+
shared_examples_for 'limiting cases' do |method|
|
62
72
|
context 'last day of the year' do
|
63
73
|
let(:zone) { Rational(-8, 24) }
|
64
74
|
let(:day) { DateTime.new(2013, 12, 31, 8, 59, 5, zone) }
|
65
75
|
|
66
76
|
it 'calculates correctly' do
|
67
|
-
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'options' do
|
72
|
-
context ':never_rises_result' do
|
73
|
-
it 'uses the supplied value, instead of nil' do
|
74
|
-
result = SunTimes.calculate(:rise, midwinter, north_cape_latitude, north_cape_longitude, {:never_rises_result => :never_rises})
|
75
|
-
expect(result).to eq(:never_rises)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context ':never_sets_result' do
|
80
|
-
it 'uses the supplied value, instead of nil' do
|
81
|
-
result = SunTimes.calculate(:rise, midsummer, north_cape_latitude, north_cape_longitude, {:never_sets_result => :never_sets})
|
82
|
-
expect(result).to eq(:never_sets)
|
83
|
-
end
|
77
|
+
subject.send(method, day, 47.5, -122)
|
84
78
|
end
|
85
79
|
end
|
86
80
|
end
|
87
81
|
|
88
82
|
describe '#rise' do
|
83
|
+
let(:rise) { Time.gm(2010, 3, 8, 5, 39, 53) }
|
84
|
+
|
89
85
|
it 'returns the sunrise time' do
|
90
|
-
result =
|
86
|
+
result = subject.rise(day, latitude, longitude)
|
91
87
|
expect(result).to be_within(1).of(rise)
|
92
88
|
end
|
89
|
+
|
90
|
+
include_examples 'timezones', :rise
|
91
|
+
include_examples 'limiting cases', :rise
|
92
|
+
include_examples 'no event', :rise
|
93
|
+
|
94
|
+
context 'options' do
|
95
|
+
include_examples 'never sets and never rises options', :rise
|
96
|
+
end
|
93
97
|
end
|
94
98
|
|
95
99
|
describe '#set' do
|
100
|
+
let(:set) { Time.gm(2010, 3, 8, 17, 11, 16) }
|
101
|
+
|
96
102
|
it 'returns the sunset time' do
|
97
|
-
result =
|
103
|
+
result = subject.set(day, latitude, longitude)
|
98
104
|
expect(result).to be_within(1).of(set)
|
99
105
|
end
|
106
|
+
|
107
|
+
include_examples 'timezones', :set
|
108
|
+
include_examples 'limiting cases', :set
|
109
|
+
include_examples 'no event', :rise
|
110
|
+
|
111
|
+
context 'options' do
|
112
|
+
include_examples 'never sets and never rises options', :set
|
113
|
+
end
|
100
114
|
end
|
101
115
|
end
|
metadata
CHANGED
@@ -1,51 +1,63 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-sun-times
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 17
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
5
11
|
platform: ruby
|
6
|
-
authors:
|
12
|
+
authors:
|
7
13
|
- Joe Yates
|
8
14
|
autorequire:
|
9
15
|
bindir: bin
|
10
16
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
17
|
+
|
18
|
+
date: 2014-01-04 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
14
22
|
name: pry
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - '>='
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
20
|
-
type: :development
|
21
23
|
prerelease: false
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
- - '>='
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
34
33
|
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
35
37
|
prerelease: false
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
41
49
|
description:
|
42
50
|
email: joe.g.yates@gmail.com
|
43
51
|
executables: []
|
52
|
+
|
44
53
|
extensions: []
|
54
|
+
|
45
55
|
extra_rdoc_files: []
|
46
|
-
|
56
|
+
|
57
|
+
files:
|
47
58
|
- .gitignore
|
48
59
|
- .rspec
|
60
|
+
- .travis.yml
|
49
61
|
- COPYING
|
50
62
|
- Gemfile
|
51
63
|
- README.md
|
@@ -55,30 +67,40 @@ files:
|
|
55
67
|
- ruby-sun-times.gemspec
|
56
68
|
- spec/spec_helper.rb
|
57
69
|
- spec/unit/ruby_sun_times_spec.rb
|
70
|
+
has_rdoc: true
|
58
71
|
homepage: https://github.com/joeyates/ruby-sun-times
|
59
72
|
licenses: []
|
60
|
-
|
73
|
+
|
61
74
|
post_install_message:
|
62
75
|
rdoc_options: []
|
63
|
-
|
76
|
+
|
77
|
+
require_paths:
|
64
78
|
- lib
|
65
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 3
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
version: "0"
|
75
97
|
requirements: []
|
98
|
+
|
76
99
|
rubyforge_project:
|
77
|
-
rubygems_version:
|
100
|
+
rubygems_version: 1.6.2
|
78
101
|
signing_key:
|
79
|
-
specification_version:
|
102
|
+
specification_version: 3
|
80
103
|
summary: Module which calculates sunrise and sunset times
|
81
|
-
test_files:
|
104
|
+
test_files:
|
82
105
|
- spec/spec_helper.rb
|
83
106
|
- spec/unit/ruby_sun_times_spec.rb
|
84
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: ecb13177df09644d48fc75563740cec84495ce00
|
4
|
-
data.tar.gz: c9002e7be0138db8ba4409844d97f7ecab102187
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 7b0a05c96603d12fcc58821a79b39ccc74a7f0b7034540b32c5aafba39cd41035dc330bb10eadcceefd4a4a8f11be523c6678901b0d600ee964d2e47a1ff1dee
|
7
|
-
data.tar.gz: 35671f27cd9a50ca1e1db445021a870bf87abb13257c544acd169e1c2a09c15088b7b7a2a26672a6d83c0060d42867729654d9e80efcbf7f973c472b96434735
|