RubySunrise 0.1.0
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/lib/sunrise.rb +190 -0
- data/rubysunrise.gemspec +12 -0
- data/test/sunrisetest.rb +89 -0
- data/test/sunsettest.rb +89 -0
- metadata +64 -0
data/lib/sunrise.rb
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
class SolarEventCalculator
|
5
|
+
|
6
|
+
@date
|
7
|
+
@latitude
|
8
|
+
@longitude
|
9
|
+
|
10
|
+
def initialize(date, latitude, longitude)
|
11
|
+
@date = date
|
12
|
+
@latitude = latitude
|
13
|
+
@longitude = longitude
|
14
|
+
end
|
15
|
+
|
16
|
+
def compute_longitude_hour
|
17
|
+
lngHour = @longitude / BigDecimal.new("15")
|
18
|
+
lngHour.round(4)
|
19
|
+
end
|
20
|
+
|
21
|
+
def compute_rise_longitude_hour
|
22
|
+
longHour = @date.yday + ((BigDecimal.new("6") - compute_longitude_hour) / BigDecimal.new("24"))
|
23
|
+
longHour.round(4)
|
24
|
+
end
|
25
|
+
|
26
|
+
def compute_set_longitude_hour
|
27
|
+
longHour = @date.yday + ((BigDecimal.new("18") - compute_longitude_hour) / BigDecimal.new("24"))
|
28
|
+
longHour.round(4)
|
29
|
+
end
|
30
|
+
|
31
|
+
def compute_sun_mean_anomaly(longHour)
|
32
|
+
constant = BigDecimal.new("0.9856")
|
33
|
+
((longHour * constant) - BigDecimal.new("3.289")).round(4)
|
34
|
+
end
|
35
|
+
|
36
|
+
def compute_sun_true_longitude(meanAnomaly)
|
37
|
+
mAsRads = degrees_as_rads(meanAnomaly)
|
38
|
+
sinM = BigDecimal.new(Math.sin(mAsRads.to_f).to_s)
|
39
|
+
sinTwoM = BigDecimal.new(Math.sin((2 * mAsRads).to_f).to_s)
|
40
|
+
firstParens = BigDecimal.new("1.916") * sinM
|
41
|
+
secondParens = BigDecimal.new("0.020") * sinTwoM
|
42
|
+
trueLong = meanAnomaly + firstParens + secondParens + BigDecimal.new("282.634")
|
43
|
+
trueLong = put_in_range(trueLong, 0, 360, 360)
|
44
|
+
trueLong.round(4)
|
45
|
+
end
|
46
|
+
|
47
|
+
def compute_right_ascension(sunTrueLong)
|
48
|
+
tanL = BigDecimal.new(Math.tan(degrees_as_rads(sunTrueLong).to_f).to_s)
|
49
|
+
ra = rads_as_degrees(BigDecimal.new(Math.atan(BigDecimal.new("0.91764") * tanL).to_s))
|
50
|
+
|
51
|
+
ra = put_in_range(ra, 0, 360, 360)
|
52
|
+
ra.round(4)
|
53
|
+
end
|
54
|
+
|
55
|
+
def put_ra_in_correct_quadrant(sunTrueLong)
|
56
|
+
lQuadrant = BigDecimal.new("90") * (sunTrueLong / BigDecimal.new("90")).floor
|
57
|
+
raQuadrant = BigDecimal.new("90") * (compute_right_ascension(sunTrueLong) / BigDecimal.new("90")).floor
|
58
|
+
|
59
|
+
ra = compute_right_ascension(sunTrueLong) + (lQuadrant - raQuadrant)
|
60
|
+
ra = ra / BigDecimal.new("15")
|
61
|
+
ra.round(4)
|
62
|
+
end
|
63
|
+
|
64
|
+
def compute_sin_sun_declination(sunTrueLong)
|
65
|
+
sinL = BigDecimal.new(Math.sin(degrees_as_rads(sunTrueLong).to_f).to_s)
|
66
|
+
sinDec = sinL * BigDecimal.new("0.39782")
|
67
|
+
sinDec.round(4)
|
68
|
+
end
|
69
|
+
|
70
|
+
def compute_cosine_sun_declination(sinSunDeclination)
|
71
|
+
cosDec = BigDecimal.new(Math.cos(Math.asin(sinSunDeclination)).to_s)
|
72
|
+
cosDec.round(4)
|
73
|
+
end
|
74
|
+
|
75
|
+
def compute_cosine_sun_local_hour(sunTrueLong, zenith)
|
76
|
+
cosZenith = BigDecimal.new(Math.cos(degrees_as_rads(BigDecimal.new(zenith.to_s))).to_s)
|
77
|
+
sinLatitude = BigDecimal.new(Math.sin(degrees_as_rads(@latitude)).to_s)
|
78
|
+
cosLatitude = BigDecimal.new(Math.cos(degrees_as_rads(@latitude)).to_s)
|
79
|
+
|
80
|
+
sinSunDeclination = compute_sin_sun_declination(sunTrueLong)
|
81
|
+
top = cosZenith - (sinSunDeclination * sinLatitude)
|
82
|
+
bottom = compute_cosine_sun_declination(sinSunDeclination) * cosLatitude
|
83
|
+
|
84
|
+
cosLocalHour = top / bottom
|
85
|
+
cosLocalHour.round(4)
|
86
|
+
end
|
87
|
+
|
88
|
+
def compute_sunrise_local_hour_angle(cosSunLocalHour)
|
89
|
+
acosH = BigDecimal.new(Math.acos(cosSunLocalHour).to_s)
|
90
|
+
localHourAngle = BigDecimal.new("360") - rads_as_degrees(acosH)
|
91
|
+
localHourAngle = localHourAngle / BigDecimal.new("15")
|
92
|
+
localHourAngle.round(4)
|
93
|
+
end
|
94
|
+
|
95
|
+
def compute_sunset_local_hour_angle(cosSunLocalHour)
|
96
|
+
acosH = BigDecimal.new(Math.acos(cosSunLocalHour).to_s)
|
97
|
+
acosH = rads_as_degrees(acosH)
|
98
|
+
localHourAngle = acosH / BigDecimal.new("15")
|
99
|
+
localHourAngle.round(4)
|
100
|
+
end
|
101
|
+
|
102
|
+
def compute_local_mean_time(sunTrueLong, longHour, t, sunLocalHour)
|
103
|
+
h = sunLocalHour
|
104
|
+
ra = put_ra_in_correct_quadrant(sunTrueLong)
|
105
|
+
|
106
|
+
parens = BigDecimal.new("0.06571") * t
|
107
|
+
time = h + ra - parens - BigDecimal.new("6.622")
|
108
|
+
|
109
|
+
utcTime = time - longHour
|
110
|
+
utcTime = put_in_range(utcTime, 0, 24, 24)
|
111
|
+
utcTime.round(4)
|
112
|
+
end
|
113
|
+
|
114
|
+
def compute_utc_sunrise(zenith)
|
115
|
+
longHour = compute_longitude_hour
|
116
|
+
riseLongHour = compute_rise_longitude_hour
|
117
|
+
|
118
|
+
meanAnomaly = compute_sun_mean_anomaly(riseLongHour)
|
119
|
+
sunTrueLong = compute_sun_true_longitude(meanAnomaly)
|
120
|
+
cosineSunLocalHour = compute_cosine_sun_local_hour(sunTrueLong, zenith)
|
121
|
+
|
122
|
+
if(cosineSunLocalHour > BigDecimal.new("1") || cosineSunLocalHour < BigDecimal.new("-1"))
|
123
|
+
return nil
|
124
|
+
end
|
125
|
+
|
126
|
+
sunLocalHour = compute_sunrise_local_hour_angle(cosineSunLocalHour)
|
127
|
+
localMeanTime = compute_local_mean_time(sunTrueLong, longHour, riseLongHour, sunLocalHour)
|
128
|
+
|
129
|
+
timeParts = localMeanTime.to_s('F').split('.')
|
130
|
+
mins = BigDecimal.new("." + timeParts[1]) * BigDecimal.new("60")
|
131
|
+
mins = mins.truncate()
|
132
|
+
mins = pad_minutes(mins.to_i)
|
133
|
+
hours = timeParts[0]
|
134
|
+
|
135
|
+
Time.gm(@date.year, @date.mon, @date.mday, hours, pad_minutes(mins.to_i))
|
136
|
+
end
|
137
|
+
|
138
|
+
def compute_utc_sunset(zenith)
|
139
|
+
longHour = compute_longitude_hour
|
140
|
+
setLongHour = compute_set_longitude_hour
|
141
|
+
|
142
|
+
meanAnomaly = compute_sun_mean_anomaly(setLongHour)
|
143
|
+
sunTrueLong = compute_sun_true_longitude(meanAnomaly)
|
144
|
+
cosineSunLocalHour = compute_cosine_sun_local_hour(sunTrueLong, zenith)
|
145
|
+
|
146
|
+
if(cosineSunLocalHour > BigDecimal.new("1") || cosineSunLocalHour < BigDecimal.new("-1"))
|
147
|
+
return nil
|
148
|
+
end
|
149
|
+
|
150
|
+
sunLocalHour = compute_sunset_local_hour_angle(cosineSunLocalHour)
|
151
|
+
localMeanTime = compute_local_mean_time(sunTrueLong, longHour, setLongHour, sunLocalHour)
|
152
|
+
|
153
|
+
timeParts = localMeanTime.to_s('F').split('.')
|
154
|
+
mins = BigDecimal.new("." + timeParts[1]) * BigDecimal.new("60")
|
155
|
+
mins = mins.truncate()
|
156
|
+
hours = timeParts[0]
|
157
|
+
|
158
|
+
Time.gm(@date.year, @date.mon, @date.mday, hours, pad_minutes(mins.to_i))
|
159
|
+
end
|
160
|
+
|
161
|
+
def pad_minutes(minutes)
|
162
|
+
if(minutes < 10)
|
163
|
+
"0" + minutes.to_s
|
164
|
+
else
|
165
|
+
minutes
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def put_in_range(number, lower, upper, adjuster)
|
170
|
+
if number > upper then
|
171
|
+
number -= adjuster
|
172
|
+
elsif number < lower then
|
173
|
+
number += adjuster
|
174
|
+
else
|
175
|
+
number
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def degrees_as_rads(degrees)
|
180
|
+
pi = BigDecimal(Math::PI.to_s)
|
181
|
+
radian = pi / BigDecimal.new("180")
|
182
|
+
degrees * radian
|
183
|
+
end
|
184
|
+
|
185
|
+
def rads_as_degrees(radians)
|
186
|
+
pi = BigDecimal(Math::PI.to_s)
|
187
|
+
degree = BigDecimal.new("180") / pi
|
188
|
+
radians * degree
|
189
|
+
end
|
190
|
+
end
|
data/rubysunrise.gemspec
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
spec = Gem::Specification.new do | s |
|
2
|
+
s.name = "RubySunrise"
|
3
|
+
s.version = "0.1.0"
|
4
|
+
s.author = "Mike Reedell / LuckyCatLabs"
|
5
|
+
s.email = "mike@luckycatlabs.com"
|
6
|
+
s.homepage = "http://www.luckycatlabs.com"
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.summary = "Calculate the sunrise/sunset given lat/long coordinates and the date. Computes civil, official, nautical, and astronomical sunrise/sunset."
|
9
|
+
s.files = ["rubysunrise.gemspec"] + Dir.glob("lib/**/*")
|
10
|
+
s.test_files = Dir.glob("{test}/**/*test.rb")
|
11
|
+
s.has_rdoc = false
|
12
|
+
end
|
data/test/sunrisetest.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'sunrise'
|
2
|
+
|
3
|
+
describe SolarEventCalculator, "test the math for home" do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@date = Date.parse('2008-11-01') #01 November 2008
|
7
|
+
@calc = SolarEventCalculator.new(@date, BigDecimal.new("39.9537"), BigDecimal.new("-75.7850"))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns correct longitude hour" do
|
11
|
+
@calc.compute_longitude_hour.should eql(BigDecimal.new("-5.0523"))
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns correct longitude hour" do
|
15
|
+
@calc.compute_rise_longitude_hour.should eql(BigDecimal.new("306.4605"))
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns correct sunrise mean anomaly" do
|
19
|
+
@calc.compute_sun_mean_anomaly(BigDecimal.new("306.4605")).should eql(BigDecimal.new("298.7585"))
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns correct sunrise's sun true longitude" do
|
23
|
+
@calc.compute_sun_true_longitude(BigDecimal.new("298.7585")).should eql(BigDecimal.new("219.6960"))
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns correct sunrise's right ascension" do
|
27
|
+
@calc.compute_right_ascension(BigDecimal.new("219.6960")).should eql(BigDecimal.new("37.2977"))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns correct sunrise's right ascension quadrant" do
|
31
|
+
@calc.put_ra_in_correct_quadrant(BigDecimal.new("219.6960")).should eql(BigDecimal.new("14.4865"))
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns correct sunrise sin sun declination" do
|
35
|
+
@calc.compute_sin_sun_declination(BigDecimal.new("219.6960")).should eql(BigDecimal.new("-0.2541"))
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns correct sunrise cosine sun declination" do
|
39
|
+
@calc.compute_cosine_sun_declination(BigDecimal.new("-0.2541")).should eql(BigDecimal.new("0.9672"))
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns correct sunrise cosine sun local hour" do
|
43
|
+
@calc.compute_cosine_sun_local_hour(BigDecimal.new("219.6960"), 96).should eql(BigDecimal.new("0.0791"))
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns correct sunrise local hour angle" do
|
47
|
+
@calc.compute_sunrise_local_hour_angle(BigDecimal.new("0.0791")).should eql(BigDecimal.new("18.3025"))
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns correct sunrise local mean time" do
|
51
|
+
trueLong = BigDecimal.new("219.6960")
|
52
|
+
longHour = BigDecimal.new("-5.0523")
|
53
|
+
localHour = BigDecimal.new("18.3025")
|
54
|
+
t = BigDecimal.new("306.4605")
|
55
|
+
@calc.compute_local_mean_time(trueLong, longHour, t, localHour).should eql(BigDecimal.new("11.0818"))
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns correct civil sunrise time" do
|
59
|
+
@calc.compute_utc_sunrise(96).should eql(Time.gm(@date.year, @date.mon, @date.mday, 11, 4))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns correct official sunrise time" do
|
63
|
+
@calc.compute_utc_sunrise(90.8333).should eql(Time.gm(@date.year, @date.mon, @date.mday, 11, 33))
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns correct nautical sunrise time" do
|
67
|
+
@calc.compute_utc_sunrise(102).should eql(Time.gm(@date.year, @date.mon, @date.mday, 10, 32))
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns correct astronomical sunrise time" do
|
71
|
+
@calc.compute_utc_sunrise(108).should eql(Time.gm(@date.year, @date.mon, @date.mday, 10, 1))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe SolarEventCalculator, "test the math for areas where there could be no rise/set" do
|
76
|
+
|
77
|
+
it "returns correct time" do
|
78
|
+
date = Date.parse('2008-04-25') #25 April 2008
|
79
|
+
calc = SolarEventCalculator.new(date, BigDecimal.new("64.8378"), BigDecimal.new("-147.7164"))
|
80
|
+
calc.compute_utc_sunrise(108).should eql(nil)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns correct time" do
|
84
|
+
date = Date.parse('2008-04-25') #25 April 2008
|
85
|
+
calc = SolarEventCalculator.new(date, BigDecimal.new("64.8378"), BigDecimal.new("-147.7164"))
|
86
|
+
calc.compute_utc_sunrise(102).should eql(nil)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
data/test/sunsettest.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'sunrise'
|
2
|
+
|
3
|
+
describe SolarEventCalculator, "Test the sunset algorithm" do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@date = Date.parse('2008-11-01') #01 November 2008
|
7
|
+
@calc = SolarEventCalculator.new(@date, BigDecimal.new("39.9537"), BigDecimal.new("-75.7850"))
|
8
|
+
end
|
9
|
+
|
10
|
+
it "returns correct longitude hour" do
|
11
|
+
@calc.compute_longitude_hour.should eql(BigDecimal.new("-5.0523"))
|
12
|
+
end
|
13
|
+
|
14
|
+
it "returns correct longitude hour" do
|
15
|
+
@calc.compute_set_longitude_hour.should eql(BigDecimal.new("306.9605"))
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns correct sunset mean anomaly" do
|
19
|
+
@calc.compute_sun_mean_anomaly(BigDecimal.new("306.9605")).should eql(BigDecimal.new("299.2513"))
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns correct sunset's sun true longitude" do
|
23
|
+
@calc.compute_sun_true_longitude(BigDecimal.new("299.2513")).should eql(BigDecimal.new("220.1966"))
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns correct sunset's right ascension" do
|
27
|
+
@calc.compute_right_ascension(BigDecimal.new("220.1966")).should eql(BigDecimal.new("37.7890"))
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns correct sunset's right ascension quadrant" do
|
31
|
+
@calc.put_ra_in_correct_quadrant(BigDecimal.new("220.1966")).should eql(BigDecimal.new("14.5193"))
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns correct sunset sin sun declination" do
|
35
|
+
@calc.compute_sin_sun_declination(BigDecimal.new("220.1966")).should eql(BigDecimal.new("-0.2568"))
|
36
|
+
end
|
37
|
+
|
38
|
+
it "returns correct sunset cosine sun declination" do
|
39
|
+
@calc.compute_cosine_sun_declination(BigDecimal.new("-0.2541")).should eql(BigDecimal.new("0.9672"))
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns correct sunset cosine sun local hour" do
|
43
|
+
@calc.compute_cosine_sun_local_hour(BigDecimal.new("220.1966"), 96).should eql(BigDecimal.new("0.0815"))
|
44
|
+
end
|
45
|
+
|
46
|
+
it "returns correct sunset local hour angle" do
|
47
|
+
@calc.compute_sunset_local_hour_angle(BigDecimal.new("0.0815")).should eql(BigDecimal.new("5.6883"))
|
48
|
+
end
|
49
|
+
|
50
|
+
it "returns correct sunset local mean time" do
|
51
|
+
trueLong = BigDecimal.new("220.1966")
|
52
|
+
longHour = BigDecimal.new("-5.0523")
|
53
|
+
localHour = BigDecimal.new("5.6883")
|
54
|
+
t = BigDecimal.new("306.9605")
|
55
|
+
@calc.compute_local_mean_time(trueLong, longHour, t, localHour).should eql(BigDecimal.new("22.4675"))
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns correct civil sunset time" do
|
59
|
+
@calc.compute_utc_sunset(96).should eql(Time.gm(@date.year, @date.mon, @date.mday, 22, 28))
|
60
|
+
end
|
61
|
+
|
62
|
+
it "returns correct official sunset time" do
|
63
|
+
@calc.compute_utc_sunset(90.8333).should eql(Time.gm(@date.year, @date.mon, @date.mday, 21, 59))
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns correct nautical sunset time" do
|
67
|
+
@calc.compute_utc_sunset(102).should eql(Time.gm(@date.year, @date.mon, @date.mday, 23, 0))
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns correct astronomical sunset time" do
|
71
|
+
@calc.compute_utc_sunset(108).should eql(Time.gm(@date.year, @date.mon, @date.mday, 23, 31))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe SolarEventCalculator, "test the math for areas where the sun doesn't set" do
|
76
|
+
|
77
|
+
it "returns correct time" do
|
78
|
+
date = Date.parse('2008-04-25') #25 April 2008
|
79
|
+
calc = SolarEventCalculator.new(date, BigDecimal.new("64.8378"), BigDecimal.new("-147.7164"))
|
80
|
+
calc.compute_utc_sunset(108).should eql(nil)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns correct time" do
|
84
|
+
date = Date.parse('2008-04-25') #25 April 2008
|
85
|
+
calc = SolarEventCalculator.new(date, BigDecimal.new("64.8378"), BigDecimal.new("-147.7164"))
|
86
|
+
calc.compute_utc_sunset(102).should eql(nil)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: RubySunrise
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Mike Reedell / LuckyCatLabs
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-03-08 00:00:00 -05:00
|
18
|
+
default_executable:
|
19
|
+
dependencies: []
|
20
|
+
|
21
|
+
description:
|
22
|
+
email: mike@luckycatlabs.com
|
23
|
+
executables: []
|
24
|
+
|
25
|
+
extensions: []
|
26
|
+
|
27
|
+
extra_rdoc_files: []
|
28
|
+
|
29
|
+
files:
|
30
|
+
- rubysunrise.gemspec
|
31
|
+
- lib/sunrise.rb
|
32
|
+
has_rdoc: true
|
33
|
+
homepage: http://www.luckycatlabs.com
|
34
|
+
licenses: []
|
35
|
+
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options: []
|
38
|
+
|
39
|
+
require_paths:
|
40
|
+
- lib
|
41
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
segments:
|
46
|
+
- 0
|
47
|
+
version: "0"
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
requirements: []
|
56
|
+
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.3.6
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: Calculate the sunrise/sunset given lat/long coordinates and the date. Computes civil, official, nautical, and astronomical sunrise/sunset.
|
62
|
+
test_files:
|
63
|
+
- test/sunrisetest.rb
|
64
|
+
- test/sunsettest.rb
|