zmanim 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.
- checksums.yaml +7 -0
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/Gemfile +6 -0
- data/LICENSE +504 -0
- data/README.md +124 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/zmanim.rb +6 -0
- data/lib/zmanim/astronomical_calendar.rb +105 -0
- data/lib/zmanim/hebrew_calendar/hebrew_date_formatter.rb +243 -0
- data/lib/zmanim/hebrew_calendar/jewish_calendar.rb +390 -0
- data/lib/zmanim/hebrew_calendar/jewish_date.rb +397 -0
- data/lib/zmanim/limudim/anchor/day_of_month_anchor.rb +49 -0
- data/lib/zmanim/limudim/anchor/day_of_week_anchor.rb +26 -0
- data/lib/zmanim/limudim/anchor/day_of_year_anchor.rb +27 -0
- data/lib/zmanim/limudim/calculators/daf_yomi_bavli.rb +53 -0
- data/lib/zmanim/limudim/calculators/daf_yomi_yerushalmi.rb +58 -0
- data/lib/zmanim/limudim/calculators/mishna_yomis.rb +48 -0
- data/lib/zmanim/limudim/calculators/parsha.rb +91 -0
- data/lib/zmanim/limudim/calculators/tehillim_monthly.rb +43 -0
- data/lib/zmanim/limudim/cycle.rb +40 -0
- data/lib/zmanim/limudim/interval.rb +37 -0
- data/lib/zmanim/limudim/limud.rb +42 -0
- data/lib/zmanim/limudim/limud_calculator.rb +137 -0
- data/lib/zmanim/limudim/limudim_formatter.rb +168 -0
- data/lib/zmanim/limudim/unit.rb +53 -0
- data/lib/zmanim/util/astronomical_calculations.rb +34 -0
- data/lib/zmanim/util/geo_location.rb +116 -0
- data/lib/zmanim/util/hebrew_numeric_formatter.rb +67 -0
- data/lib/zmanim/util/math_helper.rb +14 -0
- data/lib/zmanim/util/noaa_calculator.rb +180 -0
- data/lib/zmanim/util/sun_times_calculator.rb +123 -0
- data/lib/zmanim/util/text_helper.rb +7 -0
- data/lib/zmanim/util/time_zone_converter.rb +20 -0
- data/lib/zmanim/version.rb +3 -0
- data/lib/zmanim/zmanim_calendar.rb +106 -0
- data/zmanim.gemspec +37 -0
- metadata +153 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module Zmanim::Util
|
3
|
+
module HebrewNumericFormatter
|
4
|
+
attr_accessor :use_geresh_gershayim
|
5
|
+
|
6
|
+
GERESH = '׳'
|
7
|
+
GERSHAYIM = '״'
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@use_geresh_gershayim = true
|
11
|
+
end
|
12
|
+
|
13
|
+
def format_hebrew_number(number, include_thousands=false)
|
14
|
+
raise ArgumentError unless (0..9999).include?(number)
|
15
|
+
descriptors = {efes: 'אפס', alafim: 'אלפים'}
|
16
|
+
one_glyphs = [''] + %w(א ב ג ד ה ו ז ח ט)
|
17
|
+
ten_glyphs = [''] + %w(י כ ל מ נ ס ע פ צ)
|
18
|
+
final_ten_glyphs = [''] + %w(י ך ל ם ן ס ע ף ץ)
|
19
|
+
hundred_glyphs = [''] + %w(ק ר ש ת תק תר תש תת תתק)
|
20
|
+
tav_taz_glyphs = %w(טו טז)
|
21
|
+
|
22
|
+
return descriptors[:efes] if number == 0
|
23
|
+
|
24
|
+
thousands, remainder = number.divmod(1000)
|
25
|
+
hundreds, remainder = remainder.divmod(100)
|
26
|
+
tens, ones = remainder.divmod(10)
|
27
|
+
|
28
|
+
str = ''
|
29
|
+
|
30
|
+
if number % 1000 == 0
|
31
|
+
return add_geresh(one_glyphs[thousands]) + ' ' + descriptors[:alafim]
|
32
|
+
elsif thousands > 0 && include_thousands
|
33
|
+
str += add_geresh(one_glyphs[thousands]) + ' '
|
34
|
+
end
|
35
|
+
|
36
|
+
str += hundred_glyphs[hundreds]
|
37
|
+
if tens == 1 and ones == 5
|
38
|
+
str += tav_taz_glyphs[0]
|
39
|
+
elsif tens == 1 and ones == 6
|
40
|
+
str += tav_taz_glyphs[1]
|
41
|
+
else
|
42
|
+
if ones == 0 && hundreds != 0
|
43
|
+
str += final_ten_glyphs[tens]
|
44
|
+
else
|
45
|
+
str += ten_glyphs[tens]
|
46
|
+
end
|
47
|
+
str += one_glyphs[ones]
|
48
|
+
end
|
49
|
+
|
50
|
+
if use_geresh_gershayim
|
51
|
+
if [hundreds, tens, ones].select{|p| p > 0}.count == 1 && hundreds <= 4
|
52
|
+
str += GERESH
|
53
|
+
else
|
54
|
+
str.insert(-2, GERSHAYIM)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
str
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def add_geresh(str)
|
64
|
+
use_geresh_gershayim ? str + GERESH : str
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require_relative 'astronomical_calculations'
|
2
|
+
require_relative 'math_helper'
|
3
|
+
|
4
|
+
module Zmanim::Util
|
5
|
+
class NOAACalculator
|
6
|
+
include AstronomicalCalculations
|
7
|
+
using Zmanim::Util::MathHelper
|
8
|
+
|
9
|
+
JULIAN_DAY_JAN_1_2000 = 2451545.0
|
10
|
+
JULIAN_DAYS_PER_CENTURY = 36525.0
|
11
|
+
|
12
|
+
def name
|
13
|
+
'US National Oceanic and Atmospheric Administration Algorithm'
|
14
|
+
end
|
15
|
+
|
16
|
+
def utc_sunrise(date, geo_location, zenith, adjust_for_elevation: false)
|
17
|
+
utc_sun_position(date, geo_location, zenith, adjust_for_elevation, :sunrise)
|
18
|
+
rescue Math::DomainError
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def utc_sunset(date, geo_location, zenith, adjust_for_elevation: false)
|
23
|
+
utc_sun_position(date, geo_location, zenith, adjust_for_elevation, :sunset)
|
24
|
+
rescue Math::DomainError
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def julian_centuries_from_julian_day(julian_day)
|
31
|
+
(julian_day - JULIAN_DAY_JAN_1_2000) / JULIAN_DAYS_PER_CENTURY
|
32
|
+
end
|
33
|
+
|
34
|
+
def julian_day_from_julian_centuries(julian_centuries)
|
35
|
+
(julian_centuries * JULIAN_DAYS_PER_CENTURY) + JULIAN_DAY_JAN_1_2000
|
36
|
+
end
|
37
|
+
|
38
|
+
def utc_sun_position(date, geo_location, zenith, adjust_for_elevation, mode)
|
39
|
+
elevation = adjust_for_elevation ? geo_location.elevation : 0.0
|
40
|
+
adjusted_zenith = adjusted_zenith(zenith, elevation)
|
41
|
+
utc_time = calculate_utc_sun_position(date.ajd,
|
42
|
+
geo_location.latitude,
|
43
|
+
-geo_location.longitude,
|
44
|
+
adjusted_zenith,
|
45
|
+
mode) # in minutes
|
46
|
+
utc_time /= 60.0 # in hours
|
47
|
+
utc_time % 24 # normalized (0...24)
|
48
|
+
end
|
49
|
+
|
50
|
+
def calculate_utc_sun_position(julian_day, latitude, longitude, zenith, mode)
|
51
|
+
julian_centuries = julian_centuries_from_julian_day(julian_day)
|
52
|
+
|
53
|
+
# first pass using solar noon
|
54
|
+
noonmin = solar_noon_utc(julian_centuries, longitude)
|
55
|
+
tnoon = julian_centuries_from_julian_day(julian_day + (noonmin / 1440.0))
|
56
|
+
first_pass = approximate_utc_sun_position(tnoon, latitude, longitude, zenith, mode)
|
57
|
+
|
58
|
+
# refine using output of first pass
|
59
|
+
trefinement = julian_centuries_from_julian_day(julian_day + (first_pass / 1440.0))
|
60
|
+
approximate_utc_sun_position(trefinement, latitude, longitude, zenith, mode)
|
61
|
+
end
|
62
|
+
|
63
|
+
def approximate_utc_sun_position(approx_julian_centuries, latitude, longitude, zenith, mode)
|
64
|
+
eq_time = equation_of_time(approx_julian_centuries)
|
65
|
+
solar_dec = solar_declination(approx_julian_centuries)
|
66
|
+
hour_angle = sun_hour_angle_at_horizon(latitude, solar_dec, zenith, mode)
|
67
|
+
|
68
|
+
delta = longitude - hour_angle.to_degrees
|
69
|
+
time_delta = delta * 4.0
|
70
|
+
720 + time_delta - eq_time
|
71
|
+
end
|
72
|
+
|
73
|
+
def sun_hour_angle_at_horizon(latitude, solar_dec, zenith, mode)
|
74
|
+
lat_r = latitude.to_radians
|
75
|
+
solar_dec_r = solar_dec.to_radians
|
76
|
+
zenith_r = zenith.to_radians
|
77
|
+
|
78
|
+
hour_angle = Math.acos(
|
79
|
+
(Math.cos(zenith_r) / (Math.cos(lat_r) * Math.cos(solar_dec_r))) -
|
80
|
+
(Math.tan(lat_r) * Math.tan(solar_dec_r))
|
81
|
+
)
|
82
|
+
|
83
|
+
hour_angle *= -1 if mode == :sunset
|
84
|
+
hour_angle # in radians
|
85
|
+
end
|
86
|
+
|
87
|
+
def solar_declination(julian_centuries)
|
88
|
+
correction = obliquity_correction(julian_centuries).to_radians
|
89
|
+
lambda = sun_apparent_longitude(julian_centuries).to_radians
|
90
|
+
sint = Math.sin(correction) * Math.sin(lambda)
|
91
|
+
Math.asin(sint).to_degrees # in degrees
|
92
|
+
end
|
93
|
+
|
94
|
+
def sun_apparent_longitude(julian_centuries)
|
95
|
+
true_longitude = sun_true_longitude(julian_centuries)
|
96
|
+
omega = 125.04 - (1934.136 * julian_centuries)
|
97
|
+
true_longitude - 0.00569 - (0.00478 * Math.sin(omega.to_radians)) # in degrees
|
98
|
+
end
|
99
|
+
|
100
|
+
def sun_true_longitude(julian_centuries)
|
101
|
+
sgml = sun_geometric_mean_longitude(julian_centuries)
|
102
|
+
center = sun_equation_of_center(julian_centuries)
|
103
|
+
sgml + center # in degrees
|
104
|
+
end
|
105
|
+
|
106
|
+
def sun_equation_of_center(julian_centuries)
|
107
|
+
mrad = sun_geometric_mean_anomaly(julian_centuries).to_radians
|
108
|
+
sinm = Math.sin(mrad)
|
109
|
+
sin2m = Math.sin(2 * mrad)
|
110
|
+
sin3m = Math.sin(3 * mrad)
|
111
|
+
|
112
|
+
(sinm * (1.914602 - (julian_centuries * (0.004817 + (0.000014 * julian_centuries))))) +
|
113
|
+
(sin2m * (0.019993 - (0.000101 * julian_centuries))) +
|
114
|
+
(sin3m * 0.000289) # in degrees
|
115
|
+
end
|
116
|
+
|
117
|
+
def solar_noon_utc(julian_centuries, longitude)
|
118
|
+
century_start = julian_day_from_julian_centuries(julian_centuries)
|
119
|
+
|
120
|
+
# first pass to yield approximate solar noon
|
121
|
+
approx_tnoon = julian_centuries_from_julian_day(century_start + (longitude / 360.0))
|
122
|
+
approx_eq_time = equation_of_time(approx_tnoon)
|
123
|
+
approx_sol_noon = 720 + (longitude * 4) - approx_eq_time
|
124
|
+
|
125
|
+
# refinement using output of first pass
|
126
|
+
tnoon = julian_centuries_from_julian_day(century_start - 0.5 + (approx_sol_noon / 1440.0))
|
127
|
+
eq_time = equation_of_time(tnoon)
|
128
|
+
720 + (longitude * 4) - eq_time
|
129
|
+
end
|
130
|
+
|
131
|
+
def equation_of_time(julian_centuries)
|
132
|
+
epsilon = obliquity_correction(julian_centuries).to_radians
|
133
|
+
sgml = sun_geometric_mean_longitude(julian_centuries).to_radians
|
134
|
+
sgma = sun_geometric_mean_anomaly(julian_centuries).to_radians
|
135
|
+
eoe = earth_orbit_eccentricity(julian_centuries)
|
136
|
+
|
137
|
+
y = Math.tan(epsilon / 2.0)
|
138
|
+
y *= y
|
139
|
+
|
140
|
+
sin2l0 = Math.sin(2.0 * sgml)
|
141
|
+
sin4l0 = Math.sin(4.0 * sgml)
|
142
|
+
cos2l0 = Math.cos(2.0 * sgml)
|
143
|
+
sinm = Math.sin(sgma)
|
144
|
+
sin2m = Math.sin( 2.0 * sgma)
|
145
|
+
|
146
|
+
eq_time = (y * sin2l0) - (2.0 * eoe * sinm) + (4.0 * eoe * y * sinm * cos2l0) - (0.5 * y * y * sin4l0) - (1.25 * eoe * eoe * sin2m)
|
147
|
+
eq_time.to_degrees * 4.0 # minutes of time
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
def earth_orbit_eccentricity(julian_centuries)
|
152
|
+
0.016708634 - (julian_centuries * (0.000042037 + (0.0000001267 * julian_centuries))) # unitless
|
153
|
+
end
|
154
|
+
|
155
|
+
def sun_geometric_mean_anomaly(julian_centuries)
|
156
|
+
anomaly = 357.52911 + (julian_centuries * (35999.05029 - (0.0001537 * julian_centuries))) # in degrees
|
157
|
+
|
158
|
+
anomaly % 360 # normalized (0...360)
|
159
|
+
end
|
160
|
+
|
161
|
+
def sun_geometric_mean_longitude(julian_centuries)
|
162
|
+
longitude = 280.46646 + (julian_centuries * (36000.76983 + (0.0003032 * julian_centuries))) # in degrees
|
163
|
+
|
164
|
+
longitude % 360 # normalized (0...360)
|
165
|
+
end
|
166
|
+
|
167
|
+
def obliquity_correction(julian_centuries)
|
168
|
+
obliquity_of_ecliptic = mean_obliquity_of_ecliptic(julian_centuries)
|
169
|
+
|
170
|
+
omega = 125.04 - (1934.136 * julian_centuries)
|
171
|
+
correction = obliquity_of_ecliptic + (0.00256 * Math.cos(omega.to_radians))
|
172
|
+
correction % 360 # normalized (0...360)
|
173
|
+
end
|
174
|
+
|
175
|
+
def mean_obliquity_of_ecliptic(julian_centuries)
|
176
|
+
seconds = 21.448 - (julian_centuries * (46.8150 + (julian_centuries * (0.00059 - (julian_centuries * 0.001813)))))
|
177
|
+
23.0 + ((26.0 + (seconds / 60)) / 60.0) # in degrees
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require_relative 'astronomical_calculations'
|
2
|
+
require_relative 'math_helper'
|
3
|
+
|
4
|
+
module Zmanim::Util
|
5
|
+
class SunTimesCalculator
|
6
|
+
include AstronomicalCalculations
|
7
|
+
using Zmanim::Util::MathHelper
|
8
|
+
|
9
|
+
def name
|
10
|
+
'US Naval Almanac Algorithm'
|
11
|
+
end
|
12
|
+
|
13
|
+
def utc_sunrise(date, geo_location, zenith, adjust_for_elevation: false)
|
14
|
+
utc_sun_position(date, geo_location, zenith, adjust_for_elevation, :sunrise)
|
15
|
+
rescue Math::DomainError
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def utc_sunset(date, geo_location, zenith, adjust_for_elevation: false)
|
20
|
+
utc_sun_position(date, geo_location, zenith, adjust_for_elevation, :sunset)
|
21
|
+
rescue Math::DomainError
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
DEG_PER_HOUR = 360.0 / 24.0
|
28
|
+
|
29
|
+
def sin_deg(deg)
|
30
|
+
Math.sin(deg.to_radians)
|
31
|
+
end
|
32
|
+
|
33
|
+
def cos_deg(deg)
|
34
|
+
Math.cos(deg.to_radians)
|
35
|
+
end
|
36
|
+
|
37
|
+
def tan_deg(deg)
|
38
|
+
Math.tan(deg.to_radians)
|
39
|
+
end
|
40
|
+
|
41
|
+
def acos_deg(x)
|
42
|
+
Math.acos(x).to_degrees
|
43
|
+
end
|
44
|
+
|
45
|
+
def asin_deg(x)
|
46
|
+
Math.asin(x).to_degrees
|
47
|
+
end
|
48
|
+
|
49
|
+
def atan_deg(x)
|
50
|
+
Math.atan(x).to_degrees
|
51
|
+
end
|
52
|
+
|
53
|
+
def utc_sun_position(date, geo_location, zenith, adjust_for_elevation, mode)
|
54
|
+
elevation = adjust_for_elevation ? geo_location.elevation : 0
|
55
|
+
adjusted_zenith = adjusted_zenith(zenith, elevation)
|
56
|
+
utc_time = calculate_utc_sun_position(date,
|
57
|
+
geo_location.latitude,
|
58
|
+
geo_location.longitude,
|
59
|
+
adjusted_zenith,
|
60
|
+
mode) # in hours
|
61
|
+
utc_time % 24 # normalized (0...24)
|
62
|
+
end
|
63
|
+
|
64
|
+
def calculate_utc_sun_position(date, latitude, longitude, zenith, mode)
|
65
|
+
day_of_year = date.yday
|
66
|
+
hours_offset = hours_from_meridian(longitude)
|
67
|
+
time_days = approx_time_days(day_of_year, hours_offset, mode)
|
68
|
+
|
69
|
+
mean_anomaly = sun_mean_anomaly(time_days)
|
70
|
+
true_long = sun_true_longitude(mean_anomaly)
|
71
|
+
right_ascension_hours = sun_right_ascension_hours(true_long)
|
72
|
+
cos_local_hour_angle = cos_local_hour_angle(true_long, latitude, zenith)
|
73
|
+
|
74
|
+
local_hour_angle = acos_deg(cos_local_hour_angle)
|
75
|
+
local_hour_angle = 360.0 - local_hour_angle if mode == :sunrise
|
76
|
+
|
77
|
+
local_hour = local_hour_angle / DEG_PER_HOUR
|
78
|
+
|
79
|
+
mean_time = local_mean_time(local_hour, right_ascension_hours, time_days)
|
80
|
+
mean_time - hours_offset
|
81
|
+
end
|
82
|
+
|
83
|
+
def local_mean_time(local_hour, right_ascension_hours, time_days)
|
84
|
+
local_hour + right_ascension_hours - (0.06571 * time_days) - 6.622
|
85
|
+
end
|
86
|
+
|
87
|
+
def cos_local_hour_angle(sun_true_long, latitude, zenith)
|
88
|
+
sin_dec = 0.39782 * sin_deg(sun_true_long)
|
89
|
+
cos_dec = cos_deg(asin_deg(sin_dec))
|
90
|
+
(cos_deg(zenith) - (sin_dec * sin_deg(latitude))) / (cos_dec * cos_deg(latitude))
|
91
|
+
end
|
92
|
+
|
93
|
+
def sun_right_ascension_hours(sun_true_long)
|
94
|
+
ra = atan_deg(0.91764 * tan_deg(sun_true_long))
|
95
|
+
l_quadrant = (sun_true_long / 90.0).floor * 90.0
|
96
|
+
ra_quadrant = (ra / 90.0).floor * 90.0
|
97
|
+
ra += (l_quadrant - ra_quadrant)
|
98
|
+
|
99
|
+
ra / DEG_PER_HOUR # in hours
|
100
|
+
end
|
101
|
+
|
102
|
+
def sun_true_longitude(sun_mean_anomaly)
|
103
|
+
true_longitude = sun_mean_anomaly +
|
104
|
+
(1.916 * sin_deg(sun_mean_anomaly)) +
|
105
|
+
(0.02 * sin_deg(2 * sun_mean_anomaly)) +
|
106
|
+
282.634
|
107
|
+
true_longitude % 360
|
108
|
+
end
|
109
|
+
|
110
|
+
def sun_mean_anomaly(time_days)
|
111
|
+
(0.9856 * time_days) - 3.289
|
112
|
+
end
|
113
|
+
|
114
|
+
def approx_time_days(day_of_year, hours_offset, mode)
|
115
|
+
mode_offset = mode == :sunrise ? 6.0 : 18.0
|
116
|
+
day_of_year + ((mode_offset - hours_offset) / 24)
|
117
|
+
end
|
118
|
+
|
119
|
+
def hours_from_meridian(longitude)
|
120
|
+
longitude / DEG_PER_HOUR
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Zmanim::Util
|
2
|
+
class TimeZoneConverter
|
3
|
+
attr_reader :time_zone
|
4
|
+
|
5
|
+
def initialize(time_zone)
|
6
|
+
@time_zone = time_zone
|
7
|
+
end
|
8
|
+
|
9
|
+
# Adjust a DateTime for the provided time zone
|
10
|
+
def modify_offset(time)
|
11
|
+
offset = offset_at(time)
|
12
|
+
time.new_offset(offset/24)
|
13
|
+
end
|
14
|
+
|
15
|
+
# offset in effect for time zone at the given time (in hours)
|
16
|
+
def offset_at(time)
|
17
|
+
time_zone.period_for_utc(time.new_offset(0)).utc_total_offset / (60 * 60).to_f
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Zmanim
|
2
|
+
class ZmanimCalendar < AstronomicalCalendar
|
3
|
+
attr_accessor :candle_lighting_offset
|
4
|
+
|
5
|
+
ZENITH_16_POINT_1 = GEOMETRIC_ZENITH + 16.1
|
6
|
+
ZENITH_8_POINT_5 = GEOMETRIC_ZENITH + 8.5
|
7
|
+
|
8
|
+
def initialize(opts={})
|
9
|
+
super
|
10
|
+
@candle_lighting_offset = opts[:candle_lighting_offset] || 18
|
11
|
+
end
|
12
|
+
|
13
|
+
def tzais(opts={degrees: 8.5})
|
14
|
+
degrees, offset = extract_degrees_offset(opts)
|
15
|
+
offset_by_minutes(sunset_offset_by_degrees(GEOMETRIC_ZENITH + degrees), offset)
|
16
|
+
end
|
17
|
+
|
18
|
+
def tzais_72
|
19
|
+
tzais(offset: 72)
|
20
|
+
end
|
21
|
+
|
22
|
+
def alos(opts={degrees: 16.1})
|
23
|
+
degrees, offset = extract_degrees_offset(opts)
|
24
|
+
offset_by_minutes(sunrise_offset_by_degrees(GEOMETRIC_ZENITH + degrees), offset)
|
25
|
+
end
|
26
|
+
|
27
|
+
def alos_72
|
28
|
+
alos(offset: -72)
|
29
|
+
end
|
30
|
+
|
31
|
+
alias_method :chatzos, :sun_transit
|
32
|
+
|
33
|
+
def sof_zman_shma(day_start, day_end)
|
34
|
+
shaos_into_day(day_start, day_end, 3)
|
35
|
+
end
|
36
|
+
|
37
|
+
def sof_zman_shma_gra
|
38
|
+
sof_zman_shma(sea_level_sunrise, sea_level_sunset)
|
39
|
+
end
|
40
|
+
|
41
|
+
def sof_zman_shma_mga
|
42
|
+
sof_zman_shma(alos_72, tzais_72)
|
43
|
+
end
|
44
|
+
|
45
|
+
def candle_lighting
|
46
|
+
offset_by_minutes(sea_level_sunset , -candle_lighting_offset)
|
47
|
+
end
|
48
|
+
|
49
|
+
def sof_zman_tfila(day_start, day_end)
|
50
|
+
shaos_into_day(day_start, day_end, 4)
|
51
|
+
end
|
52
|
+
|
53
|
+
def sof_zman_tfila_gra
|
54
|
+
sof_zman_tfila(sea_level_sunrise, sea_level_sunset)
|
55
|
+
end
|
56
|
+
|
57
|
+
def sof_zman_tfila_mga
|
58
|
+
sof_zman_tfila(alos_72, tzais_72)
|
59
|
+
end
|
60
|
+
|
61
|
+
def mincha_gedola(day_start=sea_level_sunrise, day_end=sea_level_sunset)
|
62
|
+
shaos_into_day(day_start, day_end, 6.5)
|
63
|
+
end
|
64
|
+
|
65
|
+
def mincha_ketana(day_start=sea_level_sunrise, day_end=sea_level_sunset)
|
66
|
+
shaos_into_day(day_start, day_end, 9.5)
|
67
|
+
end
|
68
|
+
|
69
|
+
def plag_hamincha(day_start=sea_level_sunrise, day_end=sea_level_sunset)
|
70
|
+
shaos_into_day(day_start, day_end, 10.75)
|
71
|
+
end
|
72
|
+
|
73
|
+
def shaah_zmanis(day_start, day_end)
|
74
|
+
temporal_hour(day_start, day_end)
|
75
|
+
end
|
76
|
+
|
77
|
+
def shaah_zmanis_gra
|
78
|
+
shaah_zmanis(sea_level_sunrise, sea_level_sunset)
|
79
|
+
end
|
80
|
+
|
81
|
+
def shaah_zmanis_mga
|
82
|
+
shaah_zmanis(alos_72, tzais_72)
|
83
|
+
end
|
84
|
+
|
85
|
+
def shaah_zmanis_by_degrees_and_offset(degrees, offset)
|
86
|
+
opts = {degrees: degrees, offset: offset}
|
87
|
+
shaah_zmanis(alos(opts.merge(offset: -offset)), tzais(opts))
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def shaos_into_day(day_start, day_end, shaos)
|
93
|
+
return unless shaah_zmanis = temporal_hour(day_start, day_end)
|
94
|
+
offset_by_minutes(day_start, (shaah_zmanis / MINUTE_MILLIS) * shaos)
|
95
|
+
end
|
96
|
+
|
97
|
+
def extract_degrees_offset(opts)
|
98
|
+
[opts[:degrees] || 0.0, opts[:offset] || 0]
|
99
|
+
end
|
100
|
+
|
101
|
+
def offset_by_minutes(time, minutes)
|
102
|
+
return unless time
|
103
|
+
time + (minutes / (60 * 24).to_f)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|