Mit dem islamischen Kalender arbeiten

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Sie müssen mit Datumsangaben im islamischen System arbeiten.

Achtung!
Es ist schwierig, wenn nicht sogar unmöglich, allgemein akzeptierte Algorithmen für den islamischen Kalender zu entwickeln. Dies liegt daran, dass ein Monat dann beginnt, wenn nach dem Neumond das erste Mal die Mondsichel zu sehen ist (d.h., tatsächlich von einem Menschen gesehen wird). Neumond kann relativ genau berechnet werden, die tatsächliche Sichtbarkeit der Mondsichel hängt von Faktoren wie dem Wetter und dem Standort des Beobachters ab. Es ist daher sehr schwierig, exakt im Voraus zu berechnen, wann ein neuer Monat beginnen wird. Darüber hinaus verlassen sich manche Muslime auf die lokale Sichtung des Mondes, während andere auf die Sichtung durch Autoritäten irgendwo in der muslimischen Welt zurückgreifen. Eine Ausnahme bildet Saudi-Arabien, da dort astronomische Berechnungen anstelle von visuellen Sichtungen verwendet werden. Die Algorithmen, die hier angegeben werden, können Abweichungen von einigen Tagen ergeben, wenn islamische Daten weit im Voraus berechnet werden.

Lösung

Der letzte Tag eines islamischen Monats kann relativ genau geschätzt werden, indem – ausgenommen während eines Schaltjahrs – ungeraden Monaten 30 Tage und geraden Monaten 29 Tage zugewiesen werden:

<xsl:template name="ckbk: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="30"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="29"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Der islamische Kalender begann mit der Hidschra, Mohammeds Flucht nach Medina. Für die meisten Muslime geschah dies zum Sonnenuntergang am 15. Juli 622 u. Z. (nach dem julianischen Kalender). Dies entspricht dem absoluten Tag 227.015, daher der Abstand von 227.014 in der ansonsten einfachen Berechnung des absoluten Tages aus dem islamischen Datum:

<xsl:template name="ckbk: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>

Die Umwandlung des absoluten Tages in das islamische Datum unterscheidet sich vom ursprünglichen Lisp-Code, aus dem heraus sie entwickelt wurde. Ich verwende Gleitkommaberechnungen, um eine Suchtechnik zu vermeiden, die in der Lisp-Implementierung eingesetzt wird. Die Autoren des Lisp-Codes hatten es vorgesehen, alle Berechnungen innerhalb der 24-Bit-Integer-Grenzen zu halten, während äußerste Genauigkeit gewahrt bleibt. Allerdings lassen sich diese Techniken nicht gut nach XSLT überführen. Angesichts der Tatsache, dass XSLT 1.0 Gleitkommaberechnungen unterstützt, erscheint es nicht sinnvoll, diese um jeden Preis vermeiden zu wollen. Die benutzten Zahlen stammen vom durchschnittlichen Mondmonat, der 29,530555... Tage besitzt. Die Monatszahl wird geschätzt und dann angepasst, falls ein Tag mit einem Wert kleiner als 1 herauskommen würde. Sobald Jahr und Tag ermittelt wurden, kann der Tag als Abstand vom ersten Tag des Jahres berechnet werden:

<xsl:template name="ckbk: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 29.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="ckbk: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>

Diskussion

Der islamische Kalender ist interessant, weil er ausschließlich auf Mondumläufen beruht und die muslimischen Monate deshalb nicht in den Jahreszeiten verankert sind. Ein islamisches Jahr hat etwa 354,36 Tage. Das erste Jahr des islamischen Kalenders wird als Jahr 1 nach der Hidschra bezeichnet, Mohammeds Flucht von Mekka nach Medina. Für gläubige Muslime hat der islamische Kalender eine hohe religiöse Bedeutung. Er beruht dabei fast immer auf visuellen Beobachtungen des Mondes. Ungefähre Kalender können mit Hilfe von Algorithmen im Voraus berechnet werden, allerdings sollten sie im Allgemeinen nur für die grobe Planung zum Einsatz kommen.

Siehe auch

Unterschiede in den Konventionen zwischen den verschiedenen islamischen Ländern werden unter The Islamic Calendar beschrieben.

  

<< zurück vor >>

 

 

 

Tipp der data2type-Redaktion:
Zum Thema XSLT bieten wir auch folgende Schulungen zur Vertiefung und professionellen Fortbildung an:

Copyright © 2006 O'Reilly Verlag GmbH & Co. KG
Für Ihren privaten Gebrauch dürfen Sie die Online-Version ausdrucken.
Ansonsten unterliegt dieses Kapitel aus dem Buch "XSLT Kochbuch" denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

O'Reilly Verlag GmbH & Co. KG, Balthasarstraße 81, 50670 Köln, kommentar(at)oreilly.de