Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT日期时间格式_Xslt_Xslt 2.0 - Fatal编程技术网

XSLT日期时间格式

XSLT日期时间格式,xslt,xslt-2.0,Xslt,Xslt 2.0,如果我有以下资料: <showtime><time>2017-01-01T15:30:01.331Z</time><time>2017-01-02T20:30:00.995Z</time></showtime> 2017-01-01T15:30:01.331Z2017-01-02T20:30:00.995Z 有没有一种方法可以使用xslt格式化日期时间,这样它既可以舍入毫秒,又可以将最后一部分更改为2位数字 结果: &l

如果我有以下资料:

<showtime><time>2017-01-01T15:30:01.331Z</time><time>2017-01-02T20:30:00.995Z</time></showtime>
2017-01-01T15:30:01.331Z2017-01-02T20:30:00.995Z
有没有一种方法可以使用xslt格式化日期时间,这样它既可以舍入毫秒,又可以将最后一部分更改为2位数字

结果:

<showtime><time>2017-01-01T15:30:01.33Z</time><time>2017-01-02T20:30:01.00Z</time></showtime>
2017-01-01T15:30:01.33Z2017-01-02T20:30:01.00Z

如果可以接受截断,并且不需要真正的舍入,那么这个简单的解决方案可以跨XSLT 1.0和2.0工作:

<xsl:template match="showtime/time">
  <xsl:copy>
    <xsl:value-of select="concat(substring(., 1, 22), 'Z')"/>
  </xsl:copy>
</xsl:template>

XSLT2中,可以使用格式化日期、格式化日期时间和格式化时间等函数

不幸的是,这些函数分别采用xs:date、xs:dateTime和xs:time值(不仅仅是字符串)。 因此,首先必须选择相应的日期/时间子字符串 (来自源内容)并创建这些日期/时间变量


然后,您可以用picture参数指定的任何格式输出这些值。

正如其他人所说,XSLT2.0中的格式dateTime基本上满足您的需要。不幸的是,在处理秒和毫秒的过程中存在一些粗糙的边缘。有两个单独的图片元素用于格式化秒和分数秒。原则上,“[s01],[f001]”用逗号分隔两位数字表示秒,三位数字表示小数秒。但是复杂的情况会出现在23.9999这样的值上

XSLT2.0说,“在分数秒组件的情况下,值被舍入到指定的大小,就像通过应用函数将值舍入到偶数(分数秒,最大宽度)一样。”然而,对于将分数秒值.9999舍入到三位数,这并不能给出一个合理的答案。没有提到将任何溢出滚动到秒值(然后可能滚动到分钟值、小时值等等)

在Functions and Operators 3.1规范中,使用最小阻力路径修复了此错误:规范更改为将值截断到指定的宽度


如果以2016-12-31T23:59:59.9999Z四舍五入到2017-01-01T00:00:00.00的方式实现四舍五入对您来说真的很重要,那么您必须自己编写逻辑。

尽管XPath 2.0提供了所有日期/时间函数,但这项任务的难度和尴尬程度令人惊讶

不管怎样,这就是我想到的。请注意,这是通过两个独立的步骤完成的:首先计算取整的dateTime值,然后格式化它。与其他人所说的不同,格式化在这里是微不足道的部分

XSLT2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="time">
    <xsl:variable name="seconds" select="3600 * hours-from-dateTime(.) + 60 * minutes-from-dateTime(.) + seconds-from-dateTime(.)" />
    <xsl:variable name="round-seconds" select="round($seconds * 100) div 100" />

    <xsl:variable name="dur" select="xs:dayTimeDuration(concat('PT', $seconds, 'S'))" />
    <xsl:variable name="round-dur" select="xs:dayTimeDuration(concat('PT', $round-seconds, 'S'))" />

    <xsl:variable name="new-dateTime" select="xs:dateTime(.) - $dur + $round-dur" />
    <xsl:copy>
        <xsl:value-of select="format-dateTime($new-dateTime, '[Y0001]-[M01]-[D01]T[H01]:[m01]:[s01].[f01][ZN]')" /> 
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>


看起来这不仅仅是格式化。
1999-12-31T23:59:59.995Z
的预期结果是什么?请选择XSLT 1.0或2.0,不要两者都选择。嗨,Michael,谢谢你的回答,我会记住从现在开始标记一个。关于您的问题,是的,它不仅仅是格式,因为它需要四舍五入,预期的完整解决方案应该是:2000-01-01T00:00:00.00ZOK,但是您将使用哪一个解决方案?根据XSLT版本的不同,答案会有根本性的不同。我使用的是v2.0。我认为预期的输出清楚地表明,单纯的截断是不可接受的。由于不知道问题的上下文,很难判断截断是否会是一个问题。不管怎样,如果我们降低了精度,似乎最多减少10毫秒而不是5毫秒是可以接受的。谢谢Thomas的回答,我确实有你目前作为绷带回答的内容,但我想看看是否有完整的四舍五入解决方案。谢谢picture参数是否支持应显示多少毫秒数字?我不这么认为。您将如何准确地设置时间
20:30:00.995
的格式,以使结果是
20:30:01.00
?@ThomasW是的,是这样的。但它不会在几秒钟内(更不用说几分钟、几小时、几天、一个月或一年)滚动。我没有在评论中继续这一主题,而是在单独的回答中回答了这里提出的问题。