JavaのEXSLT日時()意図しない出力を生成します

Lakshay Chhikara:

XSLT変換をしながらタイムゾーンは奇妙な方法で連載されました

私はXalanのとにJaxen間の実装を切り替えてみましたが、変化は認められませんでした。

manualy日付のフォーマットに見しようとしましたが、タイムゾーンを追加する方法を見つけるように見えることはできません(例えば、05:30または-08:00)それを使用。

誰もがこのような同様の問題に直面していますか?

結果プロデュース

<?xml version="1.0" encoding="UTF-8"?>
<Test xmlns:date="http://exslt.org/dates-and-times" version="1.0">
    2019-06-20T10:23:31+05:1800000
</Test>

期待される結果

<?xml version="1.0" encoding="UTF-8"?>
<Test xmlns:date="http://exslt.org/dates-and-times" version="1.0">
    2019-06-20T10:23:31+05:30
</Test>

私のサンプルコードは以下の通りです

Main.java

package test;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.TimeZone;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {
    public static void main(String[] args) {
        printTransformed(TimeZone.getTimeZone("Asia/Kolkata"));
    }

    private static void printTransformed(TimeZone timeZone) {
        TimeZone.setDefault(timeZone);
        try {
            final StreamSource source = new StreamSource(
                    Files.newInputStream(
                            Paths.get(PrintAllTimeZones1.class.getResource("/input.xml").toURI())));

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Templates xsltTemplate = transformerFactory.newTemplates(
                    new StreamSource(Files.newInputStream(
                            Paths.get(Application.class.getResource("/test.xslt").toURI()))));

            final Transformer transformer = xsltTemplate.newTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, UTF_8.name());
            final ByteArrayOutputStream out = new ByteArrayOutputStream();
            final StreamResult result = new StreamResult(out);
            transformer.transform(source, result);
            System.out.println(result.getOutputStream().toString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }
}

input.xmlに

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header/>
    <SOAP-ENV:Body>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

test.xslt

<Test version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:date="http://exslt.org/dates-and-times">
    <xsl:value-of select="date:date-time()"/>
</Test>

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.4.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

bootJar {
    baseName = 'gs-spring-boot'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile 'jaxen:jaxen'
    testCompile("junit:junit")
    compile group: 'xalan', name: 'xalan', version: '2.7.2'


    compile group: 'xmlunit', name: 'xmlunit', version: '1.6'

    compile group: 'org.apache.avro', name: 'avro', version: '1.9.0'

}
TechFree:

取得の理由2019-06-20T10を:23:31 + 05:1800000は、 DSTが(5.5時間)をオフセットとGMTを追加したXalanのExsltDatetime実装に沿ってオフセットいるためです。しかし、時間と分のオフセット計算するときにXalanの実装のバグがあるように見えます。

コード内で相殺するためのXalanのExsltDatetimeクラス

int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
// If there is no offset, we have "Coordinated
// Universal Time."
if (offset == 0)
    buff.append('Z');
 else {
    // Convert milliseconds to hours and minutes
     int hrs = offset/(60*60*1000);
     // In a few cases, the time zone may be +/-hh:30.
      int min = offset%(60*60*1000);
      char posneg = hrs < 0? '-': '+';
      buff.append(posneg + formatDigits(hrs) + ':' + formatDigits(min));
  }

上記のコードは良いです5、と時間のオフセット与えるが、分が間違っている1800000、として計算されるオフセット。

それ以外の部分は、以下のように残留オフセットから正しく分を計算する必要があります。

  // Convert milliseconds to hours and minutes
  int hrs = offset/(60*60*1000);
  // In a few cases, the time zone may be +/-hh:30.
  //get the remaining offset in ms
  offset -= (hrs*60*60*1000);
  //convert remaining offset into minutes
  int min = offset/(60*1000);
  char posneg = hrs < 0? '-': '+';
  buff.append(posneg + formatDigits(hrs) + ':' + formatDigits(min));

上記正しく30分を返す修正されたコードです。

あなたのXSLTでの現在の日付の異なる/シンプルな日付フォーマッタを使用するには、使用することができます。

<Test version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:date="xalan://java.text.SimpleDateFormat"
        xmlns:java="http://xml.apache.org/xslt/java">
               <xsl:variable name="iso-date"
                select='date:new("yyyy-MM-dd&apos;T&apos;hh:mm:ssXXX")' />
    <xsl:value-of select="java:format($iso-date, java:java.util.Date.new())"/>
</Test>

あなたも試すことができXSLT 2.0の書式設定機能を

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=228716&siteId=1