/* Copyright (c) by Ulrich Greve (2002-2003/5762-5763) */

currentDate = new Date();
currentDay = currentDate.getDate();
currentMonth = currentDate.getMonth() + 1;
currentYear = currentDate.getYear();
if (currentYear < 1900)
  currentYear += 1900;

absDate = absoluteFromGregorian(currentDay,
                    currentMonth, currentYear);
hebrewFromAbsolute(absDate);

hebrewDate = returnDateDay + " " +
          getHebrewMonthName(returnDateMonth, returnDateYear) +
          " " + returnDateYear;
document.write(hebrewDate);

function isGregorianLeapYear(year) {
  if (((year % 4) == 0) &&
      ((year % 400) != 100) &&
      ((year % 400) != 200) &&
      ((year % 400) != 300))
    return true;
  else
    return false;
}

function lastDayOfGregorianMonth(month, year) {
  switch (month) {
    case 1: return 31;
    case 2: if (isGregorianLeapYear(year))
              return 29;
            else
              return 28;
    case 3: return 31;
    case 4: return 30;
    case 5: return 31;
    case 6: return 30;
    case 7: return 31;
    case 8: return 31;
    case 9: return 30;
    case 10: return 31;
    case 11: return 30;
    case 12: return 31;
  }
}

function absoluteFromGregorian(day, month, year) {
  /* Days so far this month */
  returnValue = day;

  /* Days in prior months this year */
  for (m = 1; m < month; m++)
    returnValue += lastDayOfGregorianMonth(m, year);

  /* Days in prior years */
  returnValue += (365 * (year-1));

  /* Julian leap days in prior years ... */
  returnValue += Math.floor((year-1) / 4);

  /* ... minus prior century years ... */
  returnValue -= Math.floor((year-1) / 100);

  /* ... plus prior years divisible by 400 */
  returnValue += Math.floor((year-1) / 400);

  return (returnValue);
}

function gregorianFromAbsolute(date)
{
  /* Approximation */
  approx = Math.floor(date/366);

  /* Search forward from the approximation */
  y = approx;
  for (;;)
  {
    temp = absoluteFromGregorian(1, 1, y+1);
    if (date < temp) break;
    y++;
  }
  year = y;

  /* Search forward from January */
  m = 1;
  for (;;)
  {
    temp = absoluteFromGregorian(lastDayOfGregorianMonth
                   (m, year), m, year);
    if (date <= temp) break;
    m++;
  }
  month = m;

  /* Calculate the day by subtraction */
  temp = absoluteFromGregorian(1, month, year);
  day = date-temp+1;

  returnDateDay   = day;
  returnDateMonth = month;
  returnDateYear  = year;
}

function hebrewLeapYear(year) {
  if ((((year*7)+1) % 19) < 7)
    return true;
  else
    return false;
}

function lastMonthOfHebrewYear(year) {
  if (hebrewLeapYear(year))
    return 13;
  else
    return 12;
}

function hebrewCalendarElapsedDays(year) {
  /* Months in complete cycles so far */
  monthsElapsed = 235 * Math.floor((year-1) / 19);

  /* Regular months in this cycle */
  monthsElapsed += 12 * ((year-1) % 19);

  /* Leap months this cycle */
  monthsElapsed += Math.floor(((((year-1) % 19) * 7) + 1) / 19);

  partsElapsed = (((monthsElapsed % 1080) * 793) + 204);
  hoursElapsed = (5 +
                   (monthsElapsed * 12) +
                   (Math.floor(monthsElapsed / 1080) * 793) +
                   Math.floor(partsElapsed / 1080));

  /* Conjunction day */
  day = 1 + (29 * monthsElapsed) + Math.floor(hoursElapsed/24);

  /* Conjunction parts */
  parts = ((hoursElapsed % 24) * 1080) +
           (partsElapsed % 1080);

  /* If new moon is at or after midday, */
  if ((parts >= 19440) ||

  /* ...or is on a Tuesday... */
      (((day % 7) == 2) &&
  /* at 9 hours, 204 parts or later */
       (parts >= 9924)  &&
  /* of a common year */
       (!hebrewLeapYear(year))) ||

  /* ...or is on a Monday at... */
      (((day % 7) == 1) &&
  /* 15 hours, 589 parts or later... */
       (parts >= 16789) &&
  /* at the end of a leap year */
       (hebrewLeapYear(year-1))))
  /* Then postpone Rosh HaShanah one day */
    alternativeDay = day+1;
  else
    alternativeDay = day;                                 

  /* If Rosh HaShanah would occur on Sunday, Wednesday, */
  /* or Friday */
  if (((alternativeDay % 7) == 0) ||
      ((alternativeDay % 7) == 3) ||
      ((alternativeDay % 7) == 5))
  /* Then postpone it one (more) day and return */
    alternativeDay++;

  return (alternativeDay);                
}

function daysInHebrewYear(year)
{
  return hebrewCalendarElapsedDays(year+1) -
         hebrewCalendarElapsedDays(year);
}

function longHeshvan(year)
{
  if ((daysInHebrewYear(year) % 10) == 5)
    return true;
  else
    return false;
}

function shortKislev(year)
{
  if ((daysInHebrewYear(year) % 10) == 3)
    return true;
  else
    return false;
}

function lastDayOfHebrewMonth(month, year) {
  if ((month == 2) ||
      (month == 4) ||
      (month == 6) ||
      (month == 10) ||
      (month == 13))
    return 29;
  if ((month == 12) && (!hebrewLeapYear(year)))
    return 29;
  if ((month == 8) && (!longHeshvan(year)))
    return 29;
  if ((month == 9) && (shortKislev(year)))
    return 29;
  return 30;
}

function absoluteFromHebrew(day, month, year)
{
  /* Days so far this month */
  returnValue = day;

  /* If before Tishri */
  if (month < 7)
  {
    /* Then add days in prior months this year before and */
    /* after Nisan. */
    for (m = 7; m <= lastMonthOfHebrewYear(year); m++)
      returnValue += lastDayOfHebrewMonth(m, year);
    for (m = 1; m < month; m++)
      returnValue += lastDayOfHebrewMonth(m, year);
  }
  else
  {
    for (m = 7; m < month; m++)
      returnValue += lastDayOfHebrewMonth(m, year);
  }

  /* Days in prior years */
  returnValue += hebrewCalendarElapsedDays(year);

  /* Days elapsed before absolute date 1 */
  returnValue -= 1373429;

  return (returnValue);
}

function hebrewFromAbsolute(date)
{
  /* Approximation */
  approx = Math.floor((date+1373429) / 366);

  /* Search forward from the approximation */
  y = approx;
  for (;;)
  {
    temp = absoluteFromHebrew(1, 7, y+1);
    if (date < temp) break;
    y++;
  }
  year = y;

  /* Starting month for search for month */
  temp = absoluteFromHebrew(1, 1, year);
  if (date < temp)
    uStart = 7;
  else
    uStart = 1;

  /* Search forward from either Tishri or Nisan */
  m = uStart;
  for (;;)
  {
    temp = absoluteFromHebrew
             (lastDayOfHebrewMonth(m, year), m, year);
    if (date <= temp)
      break;
    m++;
  }
  month = m;

  /* Calculate the day by subtraction */
  temp = absoluteFromHebrew(1, month, year);
  day = date-temp+1;

  returnDateDay   = day;
  returnDateMonth = month;
  returnDateYear  = year;
}

function getHebrewMonthName(month, year) {
  switch (month) {
    case 1: return "Nisan";
    case 2: return "Iyar";
    case 3: return "Sivan";
    case 4: return "Tammuz";
    case 5: return "Av";
    case 6: return "Elul";
    case 7: return "Tishri";
    case 8: return "Heshvan";
    case 9: return "Kislev";
    case 10: return "Tevet";
    case 11: return "Shevat";
    case 12: if (hebrewLeapYear(year))
               return "Adar I";
             else
               return "Adar";
    case 13: return "Adar II";
  }
}
