zmanim 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE +504 -0
  6. data/README.md +124 -0
  7. data/Rakefile +2 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/lib/zmanim.rb +6 -0
  11. data/lib/zmanim/astronomical_calendar.rb +105 -0
  12. data/lib/zmanim/hebrew_calendar/hebrew_date_formatter.rb +243 -0
  13. data/lib/zmanim/hebrew_calendar/jewish_calendar.rb +390 -0
  14. data/lib/zmanim/hebrew_calendar/jewish_date.rb +397 -0
  15. data/lib/zmanim/limudim/anchor/day_of_month_anchor.rb +49 -0
  16. data/lib/zmanim/limudim/anchor/day_of_week_anchor.rb +26 -0
  17. data/lib/zmanim/limudim/anchor/day_of_year_anchor.rb +27 -0
  18. data/lib/zmanim/limudim/calculators/daf_yomi_bavli.rb +53 -0
  19. data/lib/zmanim/limudim/calculators/daf_yomi_yerushalmi.rb +58 -0
  20. data/lib/zmanim/limudim/calculators/mishna_yomis.rb +48 -0
  21. data/lib/zmanim/limudim/calculators/parsha.rb +91 -0
  22. data/lib/zmanim/limudim/calculators/tehillim_monthly.rb +43 -0
  23. data/lib/zmanim/limudim/cycle.rb +40 -0
  24. data/lib/zmanim/limudim/interval.rb +37 -0
  25. data/lib/zmanim/limudim/limud.rb +42 -0
  26. data/lib/zmanim/limudim/limud_calculator.rb +137 -0
  27. data/lib/zmanim/limudim/limudim_formatter.rb +168 -0
  28. data/lib/zmanim/limudim/unit.rb +53 -0
  29. data/lib/zmanim/util/astronomical_calculations.rb +34 -0
  30. data/lib/zmanim/util/geo_location.rb +116 -0
  31. data/lib/zmanim/util/hebrew_numeric_formatter.rb +67 -0
  32. data/lib/zmanim/util/math_helper.rb +14 -0
  33. data/lib/zmanim/util/noaa_calculator.rb +180 -0
  34. data/lib/zmanim/util/sun_times_calculator.rb +123 -0
  35. data/lib/zmanim/util/text_helper.rb +7 -0
  36. data/lib/zmanim/util/time_zone_converter.rb +20 -0
  37. data/lib/zmanim/version.rb +3 -0
  38. data/lib/zmanim/zmanim_calendar.rb +106 -0
  39. data/zmanim.gemspec +37 -0
  40. metadata +153 -0
@@ -0,0 +1,124 @@
1
+ # Zmanim
2
+
3
+ A Ruby library for Zmanim.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'zmanim'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install zmanim
20
+
21
+ ## Usage
22
+
23
+ Some common examples include...
24
+
25
+ #### Zmanim calculations
26
+
27
+ ```ruby
28
+
29
+ # Initialize a new ZmanimCalendar object, defaults to using today's date in GMT, located at Greenwich, England
30
+ zmanim = Zmanim::ZmanimCalendar.new
31
+ #=> #<Zmanim::ZmanimCalendar:0x007fa73c2ec7d8 @geo_location=#<Zmanim::Util::GeoLocation:0x007fa73c2ec710 @location_name="Greenwich, England", @latitude=51.4772, @longitude=0, @time_zone=#<TZInfo::DataTimezone: GMT>, @elevation=0>, @date=#<Date: 2018-01-09 ((2458128j,0s,0n),+0s,2299161j)>, @astronomical_calculator=#<Zmanim::Util::NOAACalculator:0x007fa73c24e920>, @candle_lighting_offset=18>
32
+
33
+ # Calculate the sunset for today at that location
34
+ zmanim.sunset
35
+ #=> #<DateTime: 2018-01-08T16:10:12+00:00 ((2458127j,58212s,336684777n),+0s,2299161j)>
36
+
37
+ # Prepare a new location
38
+ location = Zmanim::Util::GeoLocation.new('Lakewood, NJ', 40.0721087, -74.2400243, 'US/Eastern', elevation: 15)
39
+ #=> #<Zmanim::Util::GeoLocation:0x007fa73c1c5008 @location_name="Lakewood, NJ", @latitude=40.0721087, @longitude=-74.2400243, @time_zone=#<TZInfo::DataTimezone: US/Eastern>, @elevation=15>
40
+
41
+ # Initialize a new ZmanimCalendar object, passing a specific location and date
42
+ zmanim = Zmanim::ZmanimCalendar.new(geo_location: location, date: Date.parse('2017-12-15'))
43
+ #=> #<Zmanim::ZmanimCalendar:0x007fa73c33ee98 @geo_location=#<Zmanim::Util::GeoLocation:0x007fa73c1c5008 @location_name="Lakewood, NJ", @latitude=40.0721087, @longitude=-74.2400243, @time_zone=#<TZInfo::DataTimezone: US/Eastern>, @elevation=15>, @date=#<Date: 2017-12-15 ((2458103j,0s,0n),+0s,2299161j)>, @astronomical_calculator=#<Zmanim::Util::NOAACalculator:0x007fa73c33ee48>, @candle_lighting_offset=18>
44
+
45
+ # Calculate Sof Zman Krias Shma for that location/date per the opinion of GR"A
46
+ zmanim.sof_zman_shma_gra
47
+ #=> #<DateTime: 2017-12-15T09:32:09-05:00 ((2458103j,52329s,383390214n),-18000s,2299161j)>
48
+ ```
49
+
50
+ #### Date Calculations
51
+
52
+ ```ruby
53
+ # Initialize a new JewishDate object with today's date
54
+ date = Zmanim::HebrewCalendar::JewishDate.new
55
+ # => #<Zmanim::HebrewCalendar::JewishDate:0x007fa73c2976e8 @gregorian_date=#<Date: 2018-01-09 ((2458128j,0s,0n),+0s,-Infj)>, @absolute_date=736703, @day_of_week=3, @molad_chalakim=0, @molad_minutes=0, @molad_hours=0, @jewish_year=5778, @jewish_month=10, @jewish_day=22>
56
+
57
+ # Initialize a HebrewDateFormatter object
58
+ formatter = Zmanim::HebrewCalendar::HebrewDateFormatter.new
59
+ #=> #<Zmanim::HebrewCalendar::HebrewDateFormatter:0x007fa73c2ec558 ...>
60
+
61
+ # Format the jewish date
62
+ formatter.format(date)
63
+ #=> "22 Teves, 5778"
64
+
65
+ # Change the formatter to use hebrew
66
+ formatter.hebrew_format = true
67
+ formatter.format(date)
68
+ #=> "כ״ב טבת תשע״ח"
69
+ ```
70
+
71
+ #### Jewish Calendar occasions
72
+
73
+ ```ruby
74
+ # Initialize a new JewishCalendar object with a specific Jewish date
75
+ calendar = Zmanim::HebrewCalendar::JewishCalendar.new(5778, 7, 4)
76
+ # => #<Zmanim::HebrewCalendar::JewishCalendar:0x007fa73c256ad0 @gregorian_date=#<Date: 2017-09-24 ((2458021j,0s,0n),+0s,-Infj)>, @absolute_date=736596, @day_of_week=1, @molad_chalakim=0, @molad_minutes=0, @molad_hours=0, @jewish_year=5778, @jewish_month=7, @jewish_day=4, @in_israel=false, @use_modern_holidays=false>
77
+
78
+ formatter = Zmanim::HebrewCalendar::HebrewDateFormatter.new
79
+
80
+ # Format the name of a significant day
81
+ formatter.format_significant_day(calendar)
82
+ #=> "Fast of Gedalyah"
83
+
84
+ # Format the name of a significant shabbos
85
+ calendar.set_jewish_date(5778, 7, 3)
86
+ formatter.format_significant_shabbos(calendar)
87
+ #=> "Shabbos Shuva"
88
+ ```
89
+
90
+ #### Learning cycles
91
+
92
+ ```ruby
93
+ # Fetch the daf for a calendar day
94
+ daf = calendar.daf_yomi_bavli
95
+ #=> #<Zmanim::Limudim::Limud:0x007fa73c1c7c40 ...>
96
+ daf.description
97
+ #=> "sanhedrin 69"
98
+
99
+ # Format the daf
100
+ limud_formatter = Zmanim::Limudim::LimudimFormatter.new
101
+ limud_formatter.hebrew_format = true
102
+ limud_formatter.format_talmudic(daf)
103
+ #=> "סנהדרין סט"
104
+
105
+ # Format the parsha of the week
106
+ parsha = calendar.parshas_hashavua
107
+ limud_formatter.format_parsha(parsha)
108
+ #=> "פרשת האזינו"
109
+ ```
110
+
111
+ There is much more functionality included than demonstrated here. Feel free to experiment or read the source code to learn more!
112
+
113
+ ---
114
+ ## Development
115
+
116
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
117
+
118
+ ## Contributing
119
+
120
+ Bug reports and pull requests are welcome on GitHub at https://github.com/pinnymz/ruby-zmanim. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
121
+
122
+ ## Code of Conduct
123
+
124
+ Everyone interacting in the Zmanim project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/pinnymz/ruby-zmanim/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "zmanim"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,6 @@
1
+ require 'tzinfo'
2
+ Dir[File.dirname(__FILE__) + "/**/*.rb"].each {|file| require file }
3
+
4
+ module Zmanim
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,105 @@
1
+ module Zmanim
2
+ class AstronomicalCalendar
3
+ attr_accessor :geo_location,
4
+ :astronomical_calculator,
5
+ :date
6
+
7
+ GEOMETRIC_ZENITH = 90
8
+ CIVIL_ZENITH = 96
9
+ NAUTICAL_ZENITH = 102
10
+ ASTRONOMICAL_ZENITH = 108
11
+
12
+ MINUTE_MILLIS = 60 * 1000
13
+ HOUR_MILLIS = MINUTE_MILLIS * 60
14
+
15
+ def initialize(opts={})
16
+ @geo_location = opts[:geo_location] || Util::GeoLocation.GMT
17
+ @date = opts[:date] || Date.today
18
+ @astronomical_calculator = opts[:calculator] || Util::NOAACalculator.new
19
+ end
20
+
21
+ def sunrise
22
+ date_time_from_time_of_day utc_sunrise(GEOMETRIC_ZENITH), :sunrise
23
+ end
24
+
25
+ def sea_level_sunrise
26
+ sunrise_offset_by_degrees(GEOMETRIC_ZENITH)
27
+ end
28
+
29
+ def sunrise_offset_by_degrees(offset_zenith)
30
+ date_time_from_time_of_day utc_sea_level_sunrise(offset_zenith), :sunrise
31
+ end
32
+
33
+ def sunset
34
+ date_time_from_time_of_day utc_sunset(GEOMETRIC_ZENITH), :sunset
35
+ end
36
+
37
+ def sea_level_sunset
38
+ sunset_offset_by_degrees(GEOMETRIC_ZENITH)
39
+ end
40
+
41
+ def sunset_offset_by_degrees(offset_zenith)
42
+ date_time_from_time_of_day utc_sea_level_sunset(offset_zenith), :sunset
43
+ end
44
+
45
+ def utc_sunrise(zenith)
46
+ astronomical_calculator.utc_sunrise(adjusted_date, geo_location, zenith, adjust_for_elevation: true)
47
+ end
48
+
49
+ def utc_sunset(zenith)
50
+ astronomical_calculator.utc_sunset(adjusted_date, geo_location, zenith, adjust_for_elevation: true)
51
+ end
52
+
53
+ def utc_sea_level_sunrise(zenith)
54
+ astronomical_calculator.utc_sunrise(adjusted_date, geo_location, zenith, adjust_for_elevation: false)
55
+ end
56
+
57
+ def utc_sea_level_sunset(zenith)
58
+ astronomical_calculator.utc_sunset(adjusted_date, geo_location, zenith, adjust_for_elevation: false)
59
+ end
60
+
61
+ def temporal_hour(sunrise=sea_level_sunrise, sunset=sea_level_sunset)
62
+ return unless sunset && sunrise
63
+ daytime_hours = ((sunset - sunrise) * 24).to_f
64
+ (daytime_hours / 12) * HOUR_MILLIS
65
+ end
66
+
67
+ def sun_transit
68
+ sunrise = sea_level_sunrise
69
+ sunset = sea_level_sunset
70
+ return unless sunrise && sunset
71
+ noon_hour = (temporal_hour(sunrise, sunset) / HOUR_MILLIS) * 6.0
72
+ sunrise + (noon_hour / 24.0)
73
+ end
74
+
75
+ private
76
+
77
+ def adjusted_date
78
+ date + geo_location.antimeridian_adjustment
79
+ end
80
+
81
+ # returns DateTime adjusted for the provided Time Zone
82
+ def date_time_from_time_of_day(time_of_day, mode)
83
+ return unless time_of_day
84
+ hours, remainder = (time_of_day * 3600).divmod 3600
85
+ minutes, seconds = remainder.divmod 60
86
+ year, month, day = %i(year month day).map(&adjusted_date.method(:send))
87
+ utc_time = DateTime.new(year, month, day, hours, minutes, seconds, '0')
88
+
89
+ # adjust date if utc time reflects a wraparound from the local offset
90
+ local_offset = (geo_location.local_mean_time_offset + geo_location.standard_time_offset) / HOUR_MILLIS
91
+ if hours + local_offset > 18 && mode == :sunrise # sunrise after 6pm indicates the UTC date has occurred earlier
92
+ utc_time -= 1
93
+ elsif hours + local_offset < 6 && mode == :sunset # sunset before 6am indicates the UTC date has occurred later
94
+ utc_time += 1
95
+ end
96
+
97
+ convert_date_time_for_zone utc_time
98
+ end
99
+
100
+ def convert_date_time_for_zone(time)
101
+ converter = Util::TimeZoneConverter.new(geo_location.time_zone)
102
+ converter.modify_offset(time)
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,243 @@
1
+ # encoding: UTF-8
2
+ module Zmanim::HebrewCalendar
3
+ class HebrewDateFormatter
4
+ extend Zmanim::Util::TextHelper
5
+ include Zmanim::Util::HebrewNumericFormatter
6
+
7
+ attr_accessor :hebrew_format, :use_long_hebrew_years, :long_week_format,
8
+ :transliterated_days_of_week, :transliterated_months, :transliterated_significant_days,
9
+ :transliterated_significant_tefilos, :transliterated_significant_shabbosos,
10
+ :hebrew_days_of_week, :hebrew_months, :hebrew_significant_days, :hebrew_significant_tefilos,
11
+ :hebrew_significant_shabbosos, :hebrew_omer_prefix
12
+
13
+ HEBREW_OMER_PREFIX = 'ב'
14
+ FORMATTED_DAYS_OF_WEEK = {
15
+ transliterated: Date::DAYNAMES[0..-2] + ['Shabbos'],
16
+ hebrew: %w(ראשון שני שלישי רביעי חמישי ששי שבת)
17
+ }
18
+
19
+ FORMATTED_MONTHS = {
20
+ transliterated: Zmanim::HebrewCalendar::JewishCalendar::MONTHS.each_with_object({}){|m, h|
21
+ h[m] = titleize(m)
22
+ }.merge(adar_i: 'Adar I', adar_ii: 'Adar II'),
23
+ hebrew: {
24
+ nissan: 'ניסן',
25
+ iyar: 'אייר',
26
+ sivan: 'סיון',
27
+ tammuz: 'תמוז',
28
+ av: 'אב',
29
+ elul: 'אלול',
30
+ tishrei: 'תשרי',
31
+ cheshvan: 'חשון',
32
+ kislev: 'כסלו',
33
+ teves: 'טבת',
34
+ shevat: 'שבט',
35
+ adar: 'אדר',
36
+ adar_i: 'אדר א',
37
+ adar_ii: 'אדר ב'
38
+ }
39
+ }
40
+
41
+ FORMATTED_SIGNIFICANT_DAYS = {
42
+ transliterated: Zmanim::HebrewCalendar::JewishCalendar::SIGNIFICANT_DAYS.each_with_object({}){|d, h|
43
+ h[d] = titleize(d)
44
+ }.merge(tzom_gedalyah: 'Fast of Gedalyah', tenth_of_teves: 'Tenth of Teves', tu_beshvat: "Tu B'Shvat",
45
+ taanis_esther: 'Fast of Esther', seventeen_of_tammuz: 'Seventeenth of Tammuz',
46
+ tisha_beav: "Tisha B'Av", tu_beav: "Tu B'Av", yom_hashoah: 'Yom HaShoah', yom_haatzmaut: "Yom Ha'atzmaut"),
47
+ hebrew: {
48
+ erev_rosh_hashana: 'ערב ראש השנה',
49
+ rosh_hashana: 'ראש השנה',
50
+ tzom_gedalyah: 'צום גדליה',
51
+ erev_yom_kippur: 'ערב יום כיפור',
52
+ yom_kippur: 'יום כיפור',
53
+ erev_succos: 'ערב סוכות',
54
+ succos: 'סוכות',
55
+ chol_hamoed_succos: 'חול המועד סוכות',
56
+ hoshana_rabbah: 'הושענה רבה',
57
+ shemini_atzeres: 'שמיני עצרת',
58
+ simchas_torah: 'שמחת תורה',
59
+ chanukah: 'חנוכה',
60
+ tenth_of_teves: 'עשרה בטבת',
61
+ tu_beshvat: 'ט״ו בשבט',
62
+ taanis_esther: 'תענית אסתר',
63
+ purim: 'פורים',
64
+ shushan_purim: 'שושן פורים',
65
+ purim_katan: 'פורים קטן',
66
+ shushan_purim_katan: 'שושן פורים קטן',
67
+ erev_pesach: 'ערב פסח',
68
+ pesach: 'פסח',
69
+ chol_hamoed_pesach: 'חול המועד פסח',
70
+ pesach_sheni: 'פסח שני',
71
+ erev_shavuos: 'ערב שבועות',
72
+ shavuos: 'שבועות',
73
+ seventeen_of_tammuz: 'שבעה עשר בתמוז',
74
+ tisha_beav: 'תשעה באב',
75
+ tu_beav: 'ט״ו באב',
76
+ yom_hashoah: 'יום השואה',
77
+ yom_hazikaron: 'יום הזכרון',
78
+ yom_haatzmaut: 'יום העצמאות',
79
+ yom_yerushalayim: 'יום ירושלים',
80
+ }
81
+ }
82
+
83
+ FORMATTED_SIGNIFICANT_TEFILOS = {
84
+ transliterated: Zmanim::HebrewCalendar::JewishCalendar::SIGNIFICANT_TEFILOS.each_with_object({}){|d, h|
85
+ h[d] = titleize(d)
86
+ }.merge(begin_mashiv_haruach: 'Mashiv Haruach (beginning Mussaf)',
87
+ end_mashiv_haruach: 'Mashiv Haruach (ending Mussaf)',
88
+ begin_morid_hatal: 'Morid Hatal (beginning Mussaf)'),
89
+ hebrew: {
90
+ yaaleh_veyavo: 'יעלה ויבא',
91
+ al_hanissim: 'על הנסים',
92
+ begin_mashiv_haruach: 'משיב הרוח (מתחילים במוסף)',
93
+ end_mashiv_haruach: 'משיב הרוח (מסיימים במוסף)',
94
+ mashiv_haruach: 'משיב הרוח',
95
+ begin_morid_hatal: 'מוריד הטל (מתחילים במוסף)',
96
+ morid_hatal: 'מוריד הטל',
97
+ vesein_tal_umatar: 'ותן טל ומטר',
98
+ vesein_beracha: 'ותן ברכה',
99
+ atah_yatzarta: 'אתה יצרת',
100
+ borchi_nafshi: 'ברכי נפשי',
101
+ }
102
+ }
103
+
104
+ FORMATTED_SIGNIFICANT_SHABBOSOS = {
105
+ transliterated: Zmanim::HebrewCalendar::JewishCalendar::SIGNIFICANT_SHABBOS.each_with_object({}){|d, h|
106
+ h[d] = titleize(d)
107
+ },
108
+ hebrew: {
109
+ parshas_shekalim: 'פרשת שקלים',
110
+ parshas_zachor: 'פרשת זכור',
111
+ parshas_parah: 'פרשת פרה',
112
+ parshas_hachodesh: 'פרשת החדש',
113
+ shabbos_hagadol: 'שבת הגדול',
114
+ shabbos_shuva: 'שבת שובה',
115
+ }
116
+ }
117
+
118
+ def initialize
119
+ super # hebrew numeric formatter
120
+ @long_week_format = true
121
+ @transliterated_days_of_week = FORMATTED_DAYS_OF_WEEK[:transliterated]
122
+ @transliterated_months = FORMATTED_MONTHS[:transliterated]
123
+ @transliterated_significant_days = FORMATTED_SIGNIFICANT_DAYS[:transliterated]
124
+ @transliterated_significant_tefilos = FORMATTED_SIGNIFICANT_TEFILOS[:transliterated]
125
+ @transliterated_significant_shabbosos = FORMATTED_SIGNIFICANT_SHABBOSOS[:transliterated]
126
+ @hebrew_days_of_week = FORMATTED_DAYS_OF_WEEK[:hebrew]
127
+ @hebrew_months = FORMATTED_MONTHS[:hebrew]
128
+ @hebrew_significant_days = FORMATTED_SIGNIFICANT_DAYS[:hebrew]
129
+ @hebrew_significant_tefilos = FORMATTED_SIGNIFICANT_TEFILOS[:hebrew]
130
+ @hebrew_significant_shabbosos = FORMATTED_SIGNIFICANT_SHABBOSOS[:hebrew]
131
+ @hebrew_omer_prefix = HEBREW_OMER_PREFIX
132
+ end
133
+
134
+ def format(date)
135
+ if hebrew_format
136
+ format_hebrew_number(date.jewish_day) + ' ' + format_month(date) + ' ' + format_hebrew_number(date.jewish_year)
137
+ else
138
+ "#{date.jewish_day} #{format_month(date)}, #{date.jewish_year}"
139
+ end
140
+ end
141
+
142
+ def format_month(date)
143
+ format_month_from_name(date.jewish_month_name, date.jewish_leap_year?)
144
+ end
145
+
146
+ def format_day_of_week(date)
147
+ format_day_of_week_from_number(date.day_of_week)
148
+ end
149
+
150
+ def format_hebrew_number(number)
151
+ super(number, use_long_hebrew_years)
152
+ end
153
+
154
+ def format_significant_day(calendar)
155
+ sd = calendar.significant_day
156
+ return '' unless sd
157
+ prefix = (day_number = calendar.day_of_chanukah) ? formatted_number(day_number) + ' ' : ''
158
+ prefix + formatted_significant_day(sd)
159
+ end
160
+
161
+ def format_rosh_chodesh(calendar)
162
+ return '' unless calendar.rosh_chodesh? || calendar.erev_rosh_chodesh?
163
+ month = calendar.jewish_month
164
+ day = calendar.jewish_day
165
+ if day != 1
166
+ month += 1
167
+ month = 1 if month > calendar.months_in_jewish_year
168
+ end
169
+ month_name = calendar.jewish_month_name(month)
170
+ formatted_rosh_chodesh(calendar.erev_rosh_chodesh?) + ' ' + format_month_from_name(month_name, calendar.jewish_leap_year?)
171
+ end
172
+
173
+ def format_omer(calendar)
174
+ return '' unless number = calendar.day_of_omer
175
+ if hebrew_format
176
+ format_hebrew_number(number) + ' ' + hebrew_omer_prefix + 'עומר'
177
+ else
178
+ number == 33 ? 'Lag BaOmer' : "Omer #{number}"
179
+ end
180
+ end
181
+
182
+ def format_kviah(year)
183
+ date = year.is_a?(Numeric) ? Zmanim::HebrewCalendar::JewishDate.new(year, 7, 1) : year
184
+ kviah = date.cheshvan_kislev_kviah
185
+ rosh_hashana_day = date.day_of_week
186
+ kviah_glyph = {chaseirim: 'ח', kesidran: 'כ', shelaimim: 'ש'}[kviah]
187
+ date.jewish_month = 1
188
+ pesach_day = date.day_of_week
189
+ "#{format_hebrew_number(rosh_hashana_day)}#{kviah_glyph}#{format_hebrew_number(pesach_day)}".delete(GERESH)
190
+ end
191
+
192
+ def format_tefilah_additions(calendar, customs={walled_city: false, nusach: :ashkenaz})
193
+ additions = calendar.tefilah_additions(walled_city: customs[:walled_city], nusach: customs[:nusach])
194
+ additions.map do |addition|
195
+ hebrew_format ?
196
+ hebrew_significant_tefilos[addition] :
197
+ transliterated_significant_tefilos[addition]
198
+ end
199
+ end
200
+
201
+ def format_significant_shabbos(calendar)
202
+ return '' unless shabbos = calendar.significant_shabbos
203
+ hebrew_format ?
204
+ hebrew_significant_shabbosos[shabbos] :
205
+ transliterated_significant_shabbosos[shabbos]
206
+ end
207
+
208
+ private
209
+
210
+ # We don't consider Rosh Chodesh similar to other significant days due to overlapping complexity with Chanuka
211
+ def formatted_rosh_chodesh(is_erev)
212
+ prefix = ''
213
+ prefix += (hebrew_format ? 'ערב ' : 'Erev ') if is_erev
214
+ prefix + (hebrew_format ? 'ראש חדש' : 'Rosh Chodesh')
215
+ end
216
+
217
+ def formatted_significant_day(sd)
218
+ hebrew_format ? hebrew_significant_days[sd] : transliterated_significant_days[sd]
219
+ end
220
+
221
+ def formatted_number(number)
222
+ hebrew_format ? format_hebrew_number(number) : number.to_s
223
+ end
224
+
225
+ def format_month_from_name(month_name, is_leap_year)
226
+ month_name = :adar_i if month_name == :adar && is_leap_year
227
+ if hebrew_format
228
+ suffix = use_geresh_gershayim & month_name.to_s.start_with?('adar_') ? Zmanim::Util::HebrewNumericFormatter::GERESH : ''
229
+ hebrew_months[month_name] + suffix
230
+ else
231
+ transliterated_months[month_name]
232
+ end
233
+ end
234
+
235
+ def format_day_of_week_from_number(number)
236
+ if hebrew_format
237
+ long_week_format ? hebrew_days_of_week[number - 1] : format_hebrew_number(number)
238
+ else
239
+ transliterated_days_of_week[number - 1]
240
+ end
241
+ end
242
+ end
243
+ end