Convert Standard Calender Date to Jewish Calendar Date

by Mike Pesach

Mike Pesach provided these 2 functions to convert a standard date into the Jewish calendar.

Mike Pesach has a thing about dates. You may remember his last contribution, a calendar utility for Alpha Five. Continuing his fascination with matters calendrical, Mike has coded these 2 functions to determine the Jewish calendar date from the conventional date.

A word of background

Both the standard calendar and the Jewish religious calendar are based on the lunar cycle. The conventional calendar preserves that heritage in its 12 months. To keep the seasons in the same months each year, the conventional calendar has been tweaked with the addition of extra days to most months and the insertion of intermittent leap years.

The Jewish calendar remains a lunar calendar. Some years there are 12 months and some years there are 13 months, and the days in each month can vary from year to year (no one said it was going to be easy). The Jewish calendar is roughly based on a 19-year cycle with 7 leap years, something I learned by referring to Alan Corre's calender site. A very extensive and useful reference is maintained by Remy Landau. A review of several different calendar systems, including the Greogorian and Julian calendars, is maintained by Scott Lee.

The conversion programs

As is appropriate for a religious experience, I have no precise idea how Mike arrived at these programs, nor do I even know if they are accurate. There are 2 functions:

function get_rh as D(year as N)
' gets Jewish New Year (Rosh Hashonah)
dim td as d
dim g as n
dim s as n
dim c as n
c = -6
g = mod(year,19)+1
s = mod((11*g+c),30)
	f = floor(year/100)-floor(year/400) - 2 +\
	 765433/492480*mod(12*g,19)+mod(year,4)/4-\
	(313*year+89081)/98496
nf = int(f)
ff= f -nf
if nf >= 31
	nf = nf-30
	td = ctod("10"+chr(92)+str(nf)+str(year))
else
	td = ctod("09"+chr(92)+str(nf)+str(year))
end if
select
	case dow(td) = 2 .and. ff >= 23269/25920 .and. mod(12*g,19) >11
		td=td+1
	case dow(td) = 3 .and. ff >= 1367/2160 .and. mod(12*g,19)>6
 		td = td+2
	case dow(td) = 1 .or.  dow(td) = 4 .or. dow(td) = 6
		td = td + 1
end select
get_rh = td
end function

Script 1. The get_rh() function.

function heb_dt as C(in_date as D)
dim rh as d
dim nrh as d
dim lrh as d
dim yt as n
dim hmn(13) as n
'Get Rosh Hashanah for the cal year of the date
rh = get_rh(year(in_date)) 
'check to see if where in the next or prev hebrew year
if rh > in_date	
	'we are talking about the prev year so we get that value
	lrh = get_rh(year(in_date)-1)	
	'the difference will tell us how many days in the prev year
	yt = rh - lrh	
	'mark where to come back to after creating the array of months
	gbw = 1	
	goto make_months		'create the array
'set a marker to come back to	
goback1:		
	'The beginning date to start getting the actual date
	rddt = rh-1				
	for ri = -13 to -1 step 1	'start with 13th month and come back 
	'this will work even if	not leap year because we set 13 to 0
	ari = abs(ri)	'we are working backward but we need positive #
	'If we are going to pass the date in this month don't add month
	if rddt-hmn[ari]<in_date	
		hmo = ari								'set the month
		hdom = hmn[ari]-(rddt-in_date)	'get days left
		exit for
	else											'we are still looping
		'move the date back a whole month
		rddt = rddt - hmn[ari]		
	end if
	next									'move back a month in the year
	'set the year back one because we are working on last year
	hyr = year(rh)+3760				
else										'we are working foward
nrh =  get_rh(year(in_date)+1)	'get the next year Rosh Hashanah
'get the days to know how many
yt = nrh - rh	
'marker to get back to						
gbw = 2									
goto make_months
goback2:
'set the begining for the loop
rddt = rh								
for ri = 1 to 13 step 1
'check not to go beyond the actual date
	if rddt+hmn[ri]>in_date	
		'set the hebrew month
		hmo = ri		
		'set the day							
		hdom = in_date - rddt+1				
		exit for	'we finished the loop
	else
		'add a whole month to the rddt variable
		rddt = rddt + hmn[ri]	
	end if
next
hyr = year(rh)+3761	'set the hebrew year plus one for next year
end if
'string out the result
heb_dt = alltrim(str(hmo))+chr(47)+\
	alltrim(str(hdom))+chr(47)+alltrim(str(hyr))
end function
make_months:
hmn[1] = 30	'first create months for a simple year
hmn[2] = 29
hmn[3] = 30
hmn[4] = 29
hmn[5] = 30
hmn[6] = 29
hmn[7] = 30
hmn[8] = 29
hmn[9] = 30
hmn[10] = 29
hmn[11] = 30
hmn[12] = 29
'set the leap year to 0 so that it will not affect the loop
hmn[13] = 0	
select
	case yt = 353
		hmn[3] = 29
	case yt = 355
		hmn[2] = 30
		hmn[3] = 30
	case yt = 383
		hmn[3] = 29
		hmn[6] = 30
		hmn[7] = 29
		hmn[8] = 30
		hmn[9] = 29
		hmn[10] = 30
		hmn[11] = 29
		hmn[12] = 30
		hmn[13] = 29
	case yt = 384
		hmn[6] = 30
		hmn[7] = 29
		hmn[8] = 30
		hmn[9] = 29
		hmn[10] = 30
		hmn[11] = 29
		hmn[12] = 30
		hmn[13] = 29
	case yt = 385
		hmn[2] = 30
		hmn[3] = 30
		hmn[6] = 30
		hmn[7] = 29
		hmn[8] = 30
		hmn[9] = 29
		hmn[10] = 30
		hmn[11] = 29
		hmn[12] = 30
		hmn[13] = 29
end select
if gbw =1
	goto goback1
else 
	if gbw = 2
		goto goback2
	end if
end if

Script 2. The heb_dt() function.

Mike Pesach is a developer from NY and an active member of the NY Alpha User Group. You can email him at ifomatic@aol.com.

9/5/99

Don't forget, we need your feedback to make this site better!

Return to home