Как конвертировать тики в удобочитаемую дату и время с помощью XSLT? - PullRequest
14 голосов
/ 13 марта 2009

У меня есть XML с такими временными метками:

<node stamp="1236888746689" />

И я хотел бы отобразить их в результате HTML в виде даты со временем. Есть ли способ сделать это с помощью XSLT (любой версии)?

EDIT: Я использую XSLT2.0 с Saxon9. Базовая дата 1970-01-01 0: 00.

Ответы [ 5 ]

17 голосов
/ 13 марта 2009

Вы берете дату 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>
9 голосов
/ 13 марта 2009

Если вы используете процессор XSLT 1.0, который поддерживает функции даты EXSLT (я только что проверил это с libxslt в PHP), вы можете использовать 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(), в зависимости от того, что вам нужно.

4 голосов
/ 03 марта 2011

Запоздалый ответ, да, я знаю, но я не смог найти тот, который искал здесь, поэтому я подумал, что оплачу его своим решением.

Мой XML был несколькими узлами, выгруженными из Drupal с использованием export_node и drush. Я использовал процессор xslt в PHP5, который поддерживает только 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>

Надеюсь, это поможет кому-то там. Я долго колотил головой, пока работал над этим.

1 голос
/ 13 марта 2009

Если вы хотите использовать процессор XSL 1.0, который не поддерживает функции EXSLT даты и времени , это нетривиально, но это было сделано.

Вы можете взглянуть на реализацию Katy Coe XSLT 1.0 функции "iso-from-unix" . Это часть довольно огромного «бесплатного для некоммерческого использования» набора функций даты и времени, которые она создала.

Однако ваш XSL-процессор должен поддерживать пространство имен "http://exslt.org/functions", чтобы эта реализация работала. Кроме этого нет никакой зависимости от EXSLT.

P.S .: Я знаю, что метка времени и тики Unix - это не точно одно и то же. Хотя они достаточно близки.

0 голосов
/ 13 марта 2009

XSLT равен Тьюринг завершен , поэтому должен быть способ. :) Зная хотя бы немного XSLT, он, вероятно, потребует рекурсии.

Вы не указываете точную интерпретацию своих "галочек", я полагаю, миллисекунды с какой-то эпохи, но какая? 1970

...