XSLT2.0で便利になった機能(15) 日付/時刻の関数

XSLT1.0では日付/時刻関係の関数がなく、各ベンダーごとに独自拡張が用意されていたり、MSXMLだったらJScript/VBScriptで、SaxonやXalanだったらJavaでと拡張関数を書いて呼び出しました.これらの集大成がhttp://www.exslt.org/date/index.htmlに詳しく残っています.幸いにXSLT2.0では大幅に日付/時刻関係関数が拡張されています.
 
■ current-date(), current-dateTime(), current-date()
それぞれ現在の日付、日付/時刻、日付をxs:date、xs:dateTime、xs:time形式で返してくれます.
 
■ format-date(), format-dateTime(), format-time()
current-date(), current-dateTime(), current-date()を意味ある形でxs:stringに変換するには、format-date(), format-dateTime(), format-time()関数を使用します.
 
例えば、format-dateTime(current-dateTime(),'[Y]年[M]月[D]日 [H]時[m]分')は、"2010年7月18日 21時00分"を返してくれます.2番目のpictureパラメータは、様々な形で日付/時刻の表現形を指定できます.
 
これらの3関数には、言語、カレンダー、国のオプションパラメータがありますが、Saxonでカレンダーパラメータ="JE": Japanese Calendar、言語="ja"、国="JP"を指定しても、デフォルトの英語で動作しました.Saxonでそこまで動くのを期待するのは無理だったかもしれません.
 
■ day-from-date(), day-from-dateTime()
それぞれ、xs:date、xs:dateTimeから日をxs:integerとして取得する関数です.
例えば、day-from-date(xs:date('2010-07-18'))は、18を返してくれます.
 
■ hours-from-dateTime(), hours-from-time()
それぞれxs:dateTime、xs:timeから、時刻を0~23のxs:integerとして取得する関数です.
例えば、hours-from-dateTime(xs:dateTime('2010-07-18T21:00:30 '))は、21を返してくれます.
 
■ minutes-from-dateTime(), minutes-from-time(), seconds-from-dateTime(), seconds-from-time()
それぞれ、xs:dateTime, xs:timeから分(0~59)をxs:integerとして、秒(0~59.99999....)をxs:decimalとして取得する関数です.
 
例えば、minutes-from-dateTime(xs:dateTime('2010-07-18T21:15:30 '))は15を返します.seconds-from-dateTime(xs:dateTime('2010-07-18T21:15:30 '))は30を返します.
 
■ year-from-dateTime(), year-from-date()
それぞれxs:dateTime、xs:dateから年をxs:integerとして取得する関数です.
例えばyear-from-dateTime(xs:dateTime('2010-07-18T21:15:30 '))は、2010を返します.
 
■ timezone-from-dateTime(), timezone-from-time()
それぞれxs:dateTime、xs:dateからタイムゾーンをxs:dayTimeDurationで取得する関数です.
例えばstring(timezone-from-dateTime(xs:dateTime('2010-07-18T21:15:30+09:00')))は"PT9H"を返します.(日本はUTC+09:00です.)+9時間を整数値で得るには、timezone-from-dateTime(xs:dateTime('2010-07-18T21:15:30+09:00')) div xs:dayTimeDuration('PT1H')とします.
 
xs:dayTimeDurationはxs:durationから派生した型で、日/時間レベルの期間を表します.xs:durationの表現方法は、以下のURLを参照すると良いでしょう.
 
 
■ adjust-dateTime-to-timezone(), adjust-date-to-timezone(), adjust-time-to-timezone(),
それぞれxs:dateTime, xs:date, xs:timeをxs:dayTimeDurationのタイムゾーン値を使って、新しいxs:dateTime, xs:date, xs:timeに変換します.
日本時間から、アメリ東海岸の時刻を求めるには、例えば、format-dateTime(adjust-dateTime-to-timezone(xs:dateTime('2010-07-18T21:15:30+09:00'),xs:dayTimeDuration('-PT5H')),'[Y]年[M]月[D]日 [H]時[m]分')とします.これは"2010年7月18日 7時15分"を返します.
 
アメリ東海岸タイムゾーンUTC-05:00です.
 
■ seconds-from-duration(), minutes-from-duration(), hours-from-duration(), days-from-duration(), months-from-duration(), years-from-duration()
それぞれ、xs:durationから、秒、分、時、日、月、年を、-60.0~+60.0のxs:decimal、-59~+59のxs:integer、0~23のxs:integer、xs:integer、-11~+11のxs:integer、xs:integerで返します.
 
例えばマルクスの亡くなった日は1883年3月14日です.xs:dateの引き算はxs:durationになりますから、没後の経過日数を求めることができます.days-from-duration(xs:date('2010-07-18') - xs:date('1883-03-14'))は、46512日を返します.(約没後127年)この場合、durationは"P46512D"となり、years-from-duration()は0で期待した「没後~年」を求めることはできません.SaxonとAltovaでやってみましたが同じ結果でした.
 
日付/時間関係の関数を扱うには、結構XML Schemeの知識が要るようですね.