Главная » XSLT » Исламский календарь

0

Задача

Требуется работать с датами в исламской системе летоисчисления.

Трудно, если вообще невозможно, придумать универсально пригодные ал­горитмы для исламского календаря. Связано это с тем, что месяц начина­ется в тот день, когда человек впервые видит серп луны. Вычислить даты новолуния можно абсолютно точно, но вот видимость луны зависит от та­ких факторов, как погода и положение наблюдателя. Поэтому очень слож­но заранее сказать, когда начнется новый месяц. Хуже того, некоторым мусульманам достаточно, чтобы луну увидел местный наблюдатель, тогда как другие требуют, чтобы наблюдение было произведено двумя заслужи­вающими доверия мусульманами. Исключением является Саудовская Аравия, где в основу календаря положены астрономические вычисления, а не визуальные наблюдения. Приведенные ниже алгоритмы работы с ис­ламским календарем могут давать ошибку в несколько дней.

Решение

Последний день месяца по исламскому календарю можно вычислить точно, если считать, что в нечетных месяцах 30 дней, а в четных – 29, за исключением високосных лет:

<xsl:template name="date:last-day-of-islamic-month"> <xsl:param name="month"/> <xsl:param name="year"/>

<xsl:variable name="islamic-leap-year"

select="(11 * $year + 14) mod 30 &lt; 11"/>

<xsl:choose>

<xsl:when test="$month mod 2 or ($month = 12 and $islamic-leap-year)"> <xsl:value-of select="3 0"/>

</xsl:when> <xsl:otherwise>

<xsl:value-of select="2 9"/> </xsl:otherwise> </xsl:choose> </xsl:template>

Летоисчисление по исламскому календарю начинается с Хиджры – даты пе­реселения пророка Мухаммада в Медину. Для большинства мусульман этот мо­мент совпадает с закатом солнца 15 июля 622 года н.э. (по юлианскому календарю). Этой дате соответствует абсолютный день 227 015, отсюда и слагаемое 227 014 в формуле вычисления абсолютного дня по дате исламского календаря:

<xsl:template name="date:islamic-date-to-absolute-day"> <xsl:param name="year"/> <xsl:param name="month"/> <xsl:param name="day"/>

<xsl:value-of select="$day + 29 * ($month – 1) + floor($month div 2) + 354 * ($year – 1) + floor((11 * $year + 3) div 30) + 227014"/> </xsl:template>

Преобразование абсолютного дня в исламскую дату выполняется не так, как в ори­гинальном Lisp-коде. Я воспользовался математикой с плавающей точкой, чтобы избе­жать поиска, присутствующего в реализации на Lisp. Авторы Lisp-кода стремились ог­раничиться вычислениями с 24-разрядными целыми числами, сохранив при этом максимальную точность. Однако примененные ими методы не переносятся на XSLT. Учитывая, что в XSLT 1.0 все равно используются только числа с плавающей точкой, не имеет смысла всеми силами пытаться избежать вычислений с ними. Встречающиеся в коде константы происходят от средней продолжительности лунного месяца, которая равна 29.530555… дням. Номер месяца вычисляется приближенно, а затем корректиру­ется, если в результате получается, что значения дня меньше 1. Установив, чему равны год и месяц, день можно вычислить как смещение от начала года:

<xsl:template name="date:absolute-day-to-islamic-date"> <xsl:param name="abs-day"/>

<xsl:variable name="year"

select="floor(($abs-day – 227014) div 354.36667) + 1"/>

<xsl:variable name="month"> <xsl:variable name="a"

select="$abs-day – 227014 – floor((11 * $year + 3) div 30) – 354 * ($year – 1)"/> <xsl:variable name="approx" select="floor($a div 2 9.53056)+1"/> <xsl:choose>

<xsl:when test="(29 * ($approx – 1) + floor($approx div 2)) – $a &lt; 1"> <xsl:value-of select="$approx – 1"/> </xsl:when> <xsl:otherwise>

<xsl:value-of select="$approx"/> </xsl:otherwise> </xsl:choose> </xsl:variable>

<xsl:variable name="day"> <xsl:variable name="a">

<xsl:call-template name="date:islamic-date-to-absolute-day"> <xsl:with-param name="year" select="$year"/> <xsl:with-param name="month" select="$month"/> <xsl:with-param name="day" select="1"/> </xsl:call-template> </xsl:variable>

<xsl:value-of select="$abs-day – $a + 1"/> </xsl:variable>

<xsl:value-of select="concat($year,’/’,$month,,/,,$day)"/>

</xsl:template>

Обсуждение

Календарь Хиджры или исламский календарь интересен тем, что основан толь­ко на лунных циклах, поэтому исламские месяцы попадают в разные времена года. В исламском годе приблизительно 354.36 дней. Первый день исламского календаря обозначается 1 A H. (After Hijra – после Хиджры) – дата переселения Мухаммада из Мекки в Медину. имеет глубокий религиозный смысл для правоверных мусульман и почти всегда основывается на визуальных наблюдениях за луной. Календарь на будущее можно приблизительно рассчитать, но пользовать­ся им следует только для чернового планирования.

См. также

Ближе познакомиться с мусульманским календарем можно на странице http:/ /www.sufisattari.com/calendar.html.

Соглашения, принятые в различных мусульманских странах, описаны на странице http://www.math.nus.edu.sg/aslaksen/calendar/islamic.shtml.

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии