2009-03-13 22 views
12

que tienen un XML con marcas de tiempo de la siguiente manera:¿Cómo convertir ticks en un datetime legible con XSLT?

<node stamp="1236888746689" /> 

Y me gustaría mostrarlas en el HTML como resultado la fecha con el tiempo. ¿Hay alguna manera de hacerlo con XSLT (cualquier versión)?

EDITAR: Estoy usando XSLT2.0 con Saxon9. La fecha base es 1970-01-01 0:00.

+0

Técnicamente posible, pero ineficiente y que requiere más información (como una definición de tiempo cero). Me gustaría extender esto en una extensión: ¿cuál es su plataforma? – annakata

Respuesta

13

Se toma la fecha 1970-01-01T00:00:00 y añadir tantos milisegundos como el valor del sello que dice:

<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> 
+0

¿Cómo se modificaría la respuesta para usar el texto interno en un nodo, en lugar de un atributo en él? – Broam

+0

@Broam Ajustar el ' '. –

0

XSLT es Turing complete, por lo que debe haber una manera. :) Conociendo al menos un poco de XSLT, probablemente implicará recursión.

No especifica la interpretación exacta de sus "tics", creo que son milisegundos desde hace algún tiempo, pero ¿cuál? 1970?

1

Si desea utilizar un procesador XSL 1.0 que no admite la EXSLT date and time functions esto no es trivial , pero ya está hecho.

Puede echar un vistazo a Katy Coe's XSLT 1.0 implementation of the "iso-from-unix" function. Es parte de un conjunto de funciones de fecha y hora "gratuito para uso no comercial" bastante grande que ella creó.

Sin embargo, su procesador XSL debe ser compatible con el espacio de nombres "http://exslt.org/functions" para que esta implementación funcione. Aparte de eso, no hay dependencia en EXSLT.

P.S .: Soy consciente de que una marca de tiempo Unix y las marcas no son exactamente lo mismo. Sin embargo, están lo suficientemente cerca.

8

Si está utilizando un procesador XSLT 1.0 que soporta el EXSLT date functions (I simplemente he probado esto con libxslt en PHP), puede utilizar date:add() y date:duration():

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

La función date:duration() toma un número de segundos (por lo que debe dividir sus milisegundos por 1000) y lo convierte en una "duración" (en este caso, "P14315DT20H12M26.6889998912811S"), que luego se agrega al inicio de su época (se parece a la época estándar, para este sello) con date:add() para obtener un sello de "2009-03-12T20:12:26.6889998912811Z". Puede formatear esto usando las funciones de fecha EXSLT o solo substring(), dependiendo de lo que necesite.

4

Respuesta tardía, sí, lo sé, pero no pude encontrar la que estaba buscando aquí, así que pensé en pagarla con mi solución.

Mi XML fue unos pocos nodos objeto de dumping de Drupal utilizando export_node y drush. Estaba usando el procesador xslt en PHP5, que solo es compatible con xslt 1.0. Algunas funciones EXSLT parecen ser compatibles, pero no pude decir si mi sintaxis era incorrecta o si la función que estaba tratando de usar no era compatible. De todos modos, lo siguiente funcionó para mí. Usé el código de ejemplo de w3schools.com, pero agregó una línea justo después de declarar el xsltprocessor, como a continuación:

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

PHP tiene una función trivial para la conversión de fechas, así que hice trampa y usé el procesador PHP, ya que ya lo estaba usando para transformar mi xsl.

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

Espero que esto ayude a alguien por ahí. Me estaba golpeando la cabeza por un buen rato mientras trabajaba en esto.

+1

También encontré que necesitaba usar esto: '' – kenny

Cuestiones relacionadas