如何使用 XSLT 将刻度转换为可读的日期时间?

Posted

技术标签:

【中文标题】如何使用 XSLT 将刻度转换为可读的日期时间?【英文标题】:How to convert ticks into a readable datetime with XSLT? 【发布时间】:2010-10-13 04:12:32 【问题描述】:

我有一个带有如下时间戳的 XML:

<node stamp="1236888746689" />

我想在结果 html 中将它们显示为日期和时间。 有没有办法用 XSLT(任何版本)做到这一点?

编辑: 我将 XSLT2.0 与 Saxon9 一起使用。基准日期是 1970-01-01 0:00。

【问题讨论】:

技术上可行,但效率低下且需要进一步输入(如零时间的定义)。我会将其批量处理为扩展 - 你的平台是什么? 【参考方案1】:

您将日期 1970-01-01T00:00:00 添加到戳记值告诉您的毫秒数:

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.w3.org/TR/xhtml1/strict">

    <xsl:template match="node">
        <xsl:value-of
select='xs:dateTime("1970-01-01T00:00:00") + @stamp * xs:dayTimeDuration("PT0.001S")'/>
    </xsl:template>

</xsl:stylesheet>

【讨论】:

如何修改答案以使用节点中的内部文本,而不是节点上的属性? @Broam 用&lt;xsl:attribute name="MyAttribute"&gt;&lt;/xsl:attribute&gt; 包裹&lt;xsl:value-of【参考方案2】:

迟到的答案,是的,我知道,但我在这里找不到我要找的那个,所以我想我会用我的解决方案来支付它。

我的 XML 是使用 export_node 和 drush 从 Drupal 转储的几个节点。我在 php5 中使用 xslt 处理器,它只支持 xslt 1.0。某些 EXSLT 函数似乎受支持,但我不知道是我的语法错误还是我尝试使用的函数不受支持。无论如何,以下对我有用。我使用了来自 w3schools.com 的示例代码,但在声明 xsltprocessor 后添加了一行,如下所示:

$xp = new XsltProcessor(); $xp->registerPHPFunctions();

PHP 有一个简单的日期转换功能,所以我欺骗并使用了 PHP 处理器,因为我已经在使用它来转换我的 xsl。

<xsl:for-each select="node_export/node">
  <xsl:value-of select="php:function('date', 'n-j-y', number(timestamp))"/>
</xsl:for-each>

希望这可以帮助那里的人。当我解决这个问题时,我敲了很长时间。

【讨论】:

我还发现我需要使用这个:&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl" xsl:extension-element-prefixes="php"&gt;【参考方案3】:

如果您想使用不支持 EXSLT date and time functions 的 XSL 1.0 处理器,这并非易事,但已经完成。

你可以看看Katy Coe's XSLT 1.0 implementation of the "iso-from-unix" function。这是她创建的一组相当庞大的“非商业用途免费”日期和时间函数的一部分。

但是,您的 XSL 处理器必须支持 "http://exslt.org/functions" 命名空间才能使此实现工作。除此之外,不依赖 EXSLT。

P.S.:我知道 Unix 时间戳和刻度不是 完全 相同的东西。不过,它们已经足够接近了。

【讨论】:

【参考方案4】:

如果您使用支持EXSLT date functions 的XSLT 1.0 处理器(我刚刚在PHP 中使用libxslt 对此进行了测试),您可以使用date:add()date:duration()

<xsl:value-of select="date:add('1970-01-01T00:00:00Z', date:duration(@stamp div 1000))"/>

date:duration() 函数需要几秒钟(因此您必须将毫秒除以 1000)并将其转换为“持续时间”(在本例中为“P14315DT20H12M26.6889998912811S”),然后将其添加到使用date:add() 开始您的时代(看起来像标准时代,对于这个邮票)以获得“2009-03-12T20:12:26.6889998912811Z”的邮票。然后,您可以使用 EXSLT 日期函数或仅使用 substring() 对其进行格式化,具体取决于您的需要。

【讨论】:

【参考方案5】:

XSLT 是Turing complete,所以一定有办法。 :) 至少了解一点 XSLT,它可能会涉及到递归。

您没有指定“滴答声”的确切解释,我猜自某个时代以来的毫秒数,但哪个? 1970 年?

【讨论】:

以上是关于如何使用 XSLT 将刻度转换为可读的日期时间?的主要内容,如果未能解决你的问题,请参考以下文章

Android将gmt时间转换为可读日期

将时间(自 YYYY 以来的天数给出)转换为可读的时间格式

如何在 Swift 中将多字符数字格式转换为可读的字符串?

将 ison 转换为可读的飞镖

将纪元时间戳转换为可读日期不起作用

将 dataFrame 转换为可读的,以便使用 plotly express 绘制条形图