我需要计算 XSLT 中时区的时间偏移量,这可以完成 Oracle 中 TZ_Offset 函数的功能。
例如,在 Oracle 中
Select TZ_Offset('US/Eastern') from DUAL; --returns '-04:00'
xslt 中是否有一个函数可以做同样的事情?
没有标准的 XSLT 函数可以直接执行此操作,但您可以在 XPath 3.0/3.1 中使用 format-dateTime 来实现此目的。规范是这样说的:
如果 $place 参数以 IANA 时区的形式提供 实现可以识别的名称,然后是日期或时间 正在格式化调整为适用于该时区偏移 时区。例如,如果 xs:dateTime 值 2010-02-15T12:00:00Z 格式化为 $place 参数设置为 America/New_York,然后 输出将类似于值 2010-02-15T07:00:00-05:00 提供。此调整考虑了夏令时 在可能的情况下;如果相关日期在夏令时期间 纽约时间,则调整为时区偏移 -PT4H 而不是 比-PT5H。只能使用夏令时进行调整 其中值包含日期,并且日期在 时区数据库涵盖的范围。
因此,假设您在调用该函数时处于夏令时,则
format-dateTime(current-dateTime(), '[Z00:00]', (), (), 'America/New_York')
应返回“-05:00”。这应该适用于 Saxon,但我不知道其他实现。
我还没有遇到过“美国/东部”作为时区名称:Olsen/IANA 时区数据库通常使用大陆/城市格式以避免政治争议。它可能工作也可能不工作,具体取决于底层数据库。
CREATE OR REPLACE FUNCTION FCD2_TZ_OFFSET (
INTZID IN NUMBER,
INTIMESTAMP IN TIMESTAMP
) RETURN NUMBER IS
OUTTZOFF NUMBER;
DSTSWMONTH NUMBER;
DSTSWMONTHC VARCHAR2(2);
STDSWMONTHC VARCHAR2(2);
DSTSWDAY VARCHAR2(5);
DSTSWTIME VARCHAR2(8);
STDSWMONTH NUMBER;
STDSWDAY VARCHAR2(5);
STDSWTIME VARCHAR2(8);
TZOFFADJ NUMBER;
STDTZOFF NUMBER;
INTTIMESTAMP TIMESTAMP;
INMONTH NUMBER;
INTINTS TIMESTAMP;
DSTYEAR VARCHAR2(4);
STDYEAR VARCHAR2(4);
SQLCODE NUMBER;
REQDOWDST NUMBER;
REQWOMDST NUMBER;
REQDOWSTD NUMBER;
REQWOMSTD NUMBER;
DSTSTARTTS TIMESTAMP;
STDSTARTTS TIMESTAMP;
BEGIN
IF INTIMESTAMP IS NULL THEN
INTINTS := SYSTIMESTAMP;
ELSE
INTINTS := INTIMESTAMP;
END IF;
SELECT DST_SW_MONTH, UPPER(DST_SW_DAY_CD), DST_SW_TIME, STD_SW_MONTH, UPPER(STD_SW_DAY_CD), STD_SW_TIME, TZ_OFFSET_ADJUST, STD_TZ_OFFSET,
CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' + STD_TZ_OFFSET AS TIMESTAMP), EXTRACT(MONTH FROM SYSTIMESTAMP)
INTO DSTSWMONTH, DSTSWDAY, DSTSWTIME, STDSWMONTH, STDSWDAY, STDSWTIME, TZOFFADJ, STDTZOFF, INTTIMESTAMP, INMONTH
FROM TCD2_DAYLIGHT_SV
WHERE TZ_ID = INTZID;
DSTYEAR := TO_CHAR(INTTIMESTAMP, 'YYYY');
STDYEAR := DSTYEAR;
IF DSTSWMONTH IS NULL AND DSTSWDAY IS NULL AND DSTSWTIME IS NULL AND STDSWMONTH IS NULL AND STDSWDAY IS NULL AND STDSWTIME IS NULL THEN
OUTTZOFF := STDTZOFF;
ELSE
IF DSTSWMONTH IS NOT NULL AND DSTSWMONTH BETWEEN 1 AND 12 AND
DSTSWDAY IS NOT NULL AND SUBSTR(DSTSWDAY, 1, 1) IN ('L', '2', '3', '4', '5') AND
SUBSTR(DSTSWDAY, 2, 3) IN ('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT') AND
DSTSWTIME IS NOT NULL AND STDSWMONTH IS NOT NULL AND STDSWMONTH BETWEEN 1 AND 12 AND
STDSWDAY IS NOT NULL AND SUBSTR(STDSWDAY, 1, 1) IN ('L', '1', '2', '3', '4', '5') AND
SUBSTR(STDSWDAY, 2, 3) IN ('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT') AND
STDSWTIME IS NOT