zmanim 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|