Den letzten Tag des Monats ermitteln

(Auszug aus "XSLT Kochbuch" von Sal Mangano)

Problem

Ermitteln Sie anhand eines Monats und eines Jahres den letzten Tag des Monats.

Lösung

XSLT 1.0

<xsl:template name="ckbk:last-day-of-month">
  <xsl:param name="month"/>
  <xsl:param name="year"/>
  <xsl:choose>
    <xsl:when test="$month = 2 and not($year mod 4) and ($year mod 100 or not($year mod 400))">
      <xsl:value-of select="29"/>
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="substring('312831303130313130313031', 2 * $month - 1,2)"/>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

Die Logik hinter den Berechnungen

Claus Tøndering war so freundlich, das Mysterium hinter diesen Berechnungen aufzuklären.

Damit die Formeln funktionieren, führen Sie zuerst diese Berechnungen durch:

a = (14 - monat) / 12
y = jahr - a
m = monat + 12*a - 2

Diese Berechnungen verschieben den Jahresanfang vom 1. Januar auf den 1. März. Da a=1 für Januar und Februar und 0 für alle anderen Monate, wird in diesen beiden Monaten 1 vom Jahr abgezogen. Gleichermaßen wird m zu 1 für März, 2 für April, ..., 10 für Dezember, 11 für Januar und 12 für Februar.

Sobald diese Berechnungen ausgeführt wurden, haben Sie ein Jahr, das am 1. März beginnt. Dieses Ergebnis hat zwei Vorteile. Erstens bedeutet es, dass der Schalttag an das Ende des Jahres platziert wird, was die Berechnungen vereinfacht. Zweitens bedeutet es, dass die Längen der Monate einem einfachen Muster folgen:

31 30 31 30 31 (März-Juli)
31 30 31 30 31 (August-Dezember)
31 X (Januar-Februar)

Diese Aufstellung erlaubt es Ihnen, den Ausdruck (31*m)/12 zu verwenden, um den Wochentags-Offset in jedem Monat zu berechnen.

XSLT 2.0

Sie können das 1.0-Rezept in eine Funktion überführen oder die Datumsberechnung ausnutzen und einen Tag vom ersten Tag des folgenden Monats subtrahieren. Diese Lösung ist einfacher zu verstehen, die zuvor genannte ist aber wahrscheinlich schneller:

<xsl:function name="ckbk:last-day-of-month" as="xs:integer">
  <xsl:param name="month" as="xs:integer"/>
  <xsl:param name="year" as="xs:integer"/>
  <!--Erster des Monats in angegebenem Jahr -->
  <xsl:variable name="date" select="xs:date(concat(xs:string($year),'-',format-number($month,'00'),'-01'))" as="xs:date"/>
  <xsl:variable name="m" select="xdt:yearMonthDuration('P1M')" as="xdt:yearMonthDuration"/>
  <xsl:variable name="d" select="xdt:dayTimeDuration('P1D')" as="xdt:dayTimeDuration"/>
  <xsl:sequence select="day-from-date(($date + $m) - $d)"/>
</xsl:function>

Diskussion

Eine potenzielle Anwendung für diese Funktion besteht in der Konstruktion von Seiten eines Kalenders. Sie ist relativ einfach zu verstehen, sobald Sie die Regeln kennen, nach denen ein Schaltjahr bestimmt wird. Diese Funktion wurde aus Lisp überführt, in dem die Anzahl der Tage der einzelnen Monate aus einer Liste extrahiert wird. Ich habe beschlossen, substring zu verwenden, um dieselbe Aufgabe auszuführen. Sie könnten es vorziehen, die Logik in zusätzliche when-Elemente zu verschieben. Außerdem könnten Sie die Daten über jeden Monat, einschließlich seiner Länge, in XML speichern.

Siehe auch

Siehe das Rezept Die Wochennummer fur ein bestimmtes Datum berechnen für Methoden, um Kalender-Metadaten in XML zu speichern.

  

<< 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