Class: Hebruby::HebrewDate

Inherits:
Object
  • Object
show all
Defined in:
lib/hebruby.rb

Constant Summary collapse

HEBREW_EPOCH =
347995
MONTH_NAMES =
%w{none Nissan Iyar Sivan Tamuz Av Elul Tishrei Chesvan Kislev Tevet Shvat Adar} + ["Adar Sheni"]
HEB_MONTH_NAMES =
[ nil, 'ניסן', 'אייר', 'סיון', 'תמוז', 'אב', 'אלול', 'תשרי',
'חשון', 'כסלו', 'טבת', 'שבט', 'אדר', 'אדר א\'', 'אדר ב\'']
HEB_DAYS =
[ nil, 'א\'', 'ב\'', 'ג\'', 'ד\'', 'ה\'', 'ו\'', 'ז\'', 'ח\'', 'ט\'',
'י\'', 'י"א', 'י"ב', 'י"ג', 'י"ד', 'ט"ו', 'ט"ז', 'י"ז', 'י"ח',
'י"ט', 'כ\'' , 'כ"א', 'כ"ב', 'כ"ג', 'כ"ד', 'כ"ה', 'כ"ו', 'כ"ז','כ"ח', 'כ"ט', 'ל\'' ]
ONES =
[ '', 'א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ז', 'ח', 'ט' ]
TENS =
[ '', 'י', 'כ', 'ל', 'מ', 'נ', 'ס', 'ע', 'פ', 'צ' ]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*params) ⇒ HebrewDate

Constructor. When passed 1 parameter, the one parameter must either be an integer representing a Julian day number, or some kind of date object (e.g. Ruby’s Date class) that responds to the jd method to expose a Julian day number. When passed 3 parameters, they are day,month,year of the Hebrew date, as integers.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/hebruby.rb', line 50

def initialize(*params)
  if params.size == 3
    @hd = params[0]
    @hm = params[1]
    @hy = params[2]
    convert_from_hebrew
  elsif params.size == 1
    jd=params[0]
    if jd
      if jd.is_a? Integer
        @jd = jd
      elsif jd.respond_to? :jd
        @jd = jd.jd
      else
        raise ArgumentError
      end
      convert_from_julian
    end
  else
    raise ArgumentError
  end
end

Instance Attribute Details

#hdObject

Accessors for base Hebrew day, month, and year



41
42
43
# File 'lib/hebruby.rb', line 41

def hd
  @hd
end

#hmObject

Accessors for base Hebrew day, month, and year



41
42
43
# File 'lib/hebruby.rb', line 41

def hm
  @hm
end

#hyObject

Accessors for base Hebrew day, month, and year



41
42
43
# File 'lib/hebruby.rb', line 41

def hy
  @hy
end

Class Method Details

.days_in_prior_years(year) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/hebruby.rb', line 198

def self.days_in_prior_years(year)
  months_elapsed = (year - 1) / 19 * 235 + # Months in complete cycles so far
    12 * ((year - 1) % 19) + # Regular months in this cycle
    (1 + 7 * ((year -  1) % 19)) / 19 # Leap months in this cycle
  parts_elapsed = 204 +  793 * (months_elapsed % 1080)
  hours_elapsed = 5 +
    12 * months_elapsed +
    793 * ( months_elapsed / 1080) +
    parts_elapsed / 1080
  parts = 1080 * (hours_elapsed % 24) + (parts_elapsed % 1080)
  day = 1 + 29 * months_elapsed + hours_elapsed / 24

  if parts >= 19440 or #If the new moon is at or after midday,
    ( day % 7 == 2 and #...or is on a Tuesday...
      parts >= 9924 and # at 9 hours, 204 parts or later...
      not leap?(year) # of a common year
    ) or
    ( day % 7 == 1 and #...or is on a Monday...
      parts >= 16789 and # at 15 hours, 589 parts or later...
      leap?(year - 1) # at the end of a leap year
    )
  then
    day += 1 #then postpone Rosh HaShanah one day
  end

  #If Rosh HaShanah would occur on Sunday, Wednesday, or Friday
  #Then postpone it one more day
  day += 1 if [0,3,5].include?(day % 7)

  return day + HEBREW_EPOCH + 1
end

.heb_number(num) ⇒ Object

Return the representation in hebrew letters for a number less than 100

Raises:

  • (ArgumentError)


131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/hebruby.rb', line 131

def self.heb_number(num)
  raise ArgumentError if num>100 or num < 0
  return 'ט"ו' if num == 15
  return 'ט"ז' if num == 16
  if num < 10
    return '"' + ONES[ num % 10 ]
  elsif num % 10 == 0
    return '"' + TENS[ num / 10 ]
  else
    return TENS[ num / 10 ] + '"' + ONES[ num % 10 ]
  end
end

.jd_to_hebrew(jd) ⇒ Object

Convert Julian day number to Hebrew date This works by making multiple calls to to_jd, and is this very slow



258
259
260
261
262
263
264
265
266
267
268
269
270
271
# File 'lib/hebruby.rb', line 258

def self.jd_to_hebrew(jd)
  greg_date = Date.jd(jd)
  month = [nil,9,10,11,12,1,2,3,4,7,7,7,8][greg_date.month]
  day = greg_date.mday
  year = 3760 + greg_date.year

  year += 1 while jd >= to_jd(year + 1, 7, 1)
  length = year_months(year)
  month = (1 + month % length) while jd > to_jd(year,month,month_days(year,month))

  day = jd - to_jd(year,month,1) + 1

  return [year, month, day]
end

.leap?(year) ⇒ Boolean

Is a given Hebrew year a leap year ?

Returns:

  • (Boolean)


145
146
147
# File 'lib/hebruby.rb', line 145

def self.leap?(year)
  return ((year * 7) + 1).modulo(19) < 7
end

.month_days(year, month) ⇒ Object

How many days are in a given month of a given year



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/hebruby.rb', line 161

def self.month_days(year, month)
  # First of all, dispose of fixed-length 29 day months
  case
    when (month == 2 || month == 4 || month == 6 || month == 10 || month == 13)
      return 29

    # If it's not a leap year, Adar has 29 days
    when (month == 12 && !leap?(year)) then
      return 29

    # If it's Cheshvan, days depend on length of year
    when month == 8 && year_days(year).modulo(10) != 5 then
      return 29

    # Similarly, Kislev varies with the length of year
    when (month == 9 && (year_days(year).modulo(10) == 3)) then
      return 29

    # Nope, it's a 30 day month
    else
      return 30
  end
end

.to_jd(year, month, day) ⇒ Object

Convert hebrew date to julian day number



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/hebruby.rb', line 231

def self.to_jd(year, month, day)
  months = year_months(year)

  jd = day

  if (month < 7) then
    for mon in 7..months
      jd += month_days(year, mon)
    end

    for mon in 1...month
      jd += month_days(year, mon)
    end
  else
    for mon in 7...month
      jd += month_days(year, mon)
    end
  end

  jd += days_in_prior_years(year)

  return jd
end

.year_days(year) ⇒ Object

How many days are in a Hebrew year ?



156
157
158
# File 'lib/hebruby.rb', line 156

def self.year_days(year)
  return to_jd(year + 1, 7, 1) - to_jd(year, 7, 1)
end

.year_months(year) ⇒ Object

How many months are there in a Hebrew year (12 = normal, 13 = leap)



151
152
153
# File 'lib/hebruby.rb', line 151

def self.year_months(year)
  return leap?(year) ? 13 : 12
end

Instance Method Details

#convert_from_hebrewObject

internal conversion method to keep fields syncronized with julian day number



194
195
196
# File 'lib/hebruby.rb', line 194

def convert_from_hebrew
  @jd = HebrewDate.to_jd(@hy, @hm, @hd)
end

#convert_from_julianObject

internal conversion method to keep fields syncronized with julian day number



186
187
188
189
190
191
# File 'lib/hebruby.rb', line 186

def convert_from_julian
  dateArray = HebrewDate.jd_to_hebrew(@jd)
  @hy = dateArray[0]
  @hm = dateArray[1]
  @hd = dateArray[2]
end

#dayObject



73
74
75
# File 'lib/hebruby.rb', line 73

def day
  return @hd
end

#heb_dateObject

Provide Hebrew display date



121
122
123
# File 'lib/hebruby.rb', line 121

def heb_date
  return heb_day_name + " ב" + heb_month_name + " " + heb_year_name
end

#heb_day_nameObject

Provide Hebrew day of the month, in hebrew letters.



107
108
109
# File 'lib/hebruby.rb', line 107

def heb_day_name
  return HEB_DAYS[@hd]
end

#heb_month_nameObject

Provide Hebrew month name in Hebrew letters



98
99
100
101
102
103
104
# File 'lib/hebruby.rb', line 98

def heb_month_name
  if HebrewDate.leap?(@hy) and @hm >= 12 # leap year and from adar
   return HEB_MONTH_NAMES[@hm + 1]
  else
   return HEB_MONTH_NAMES[@hm]
  end
end

#heb_year_nameObject

Provide Hebrew year number in hebrew letters

Raises:

  • (RangeError)


112
113
114
115
116
117
118
# File 'lib/hebruby.rb', line 112

def heb_year_name
  year = @hy
  raise RangeError, "only 5700 - 5899 supported" if year < 5700 || year >= 5900
  prefix = year / 100 == 57 ? "התש" : "התת"
  suffix = HebrewDate.heb_number(year % 100)
  full = prefix + suffix
end

#jdObject

return julian day number



88
89
90
# File 'lib/hebruby.rb', line 88

def jd
  return @jd
end

#julian_dateObject

return Ruby ‘Date` object



126
127
128
# File 'lib/hebruby.rb', line 126

def julian_date
  return Date.jd(@jd)
end

#monthObject

Provide Hebrew transliterated month display name



78
79
80
# File 'lib/hebruby.rb', line 78

def month
  return @hm
end

#month_nameObject

Provide Hebrew month name transiterated into Englsih



93
94
95
# File 'lib/hebruby.rb', line 93

def month_name
  return MONTH_NAMES[@hm]
end

#yearObject

return Hebrew year



83
84
85
# File 'lib/hebruby.rb', line 83

def year
  return @hy
end