Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert ticks into a readable datetime with XSLT?

I have an XML with timestamps like this:

<node stamp="1236888746689" />

And I would like to display them in the result HTML as date with time. Is there a way to do it with XSLT (any Version)?

EDIT: I am using XSLT2.0 with Saxon9. The base date is 1970-01-01 0:00.

like image 838
MrFox Avatar asked Mar 13 '09 14:03

MrFox


People also ask

What is text () in XSLT?

Definition and Usage. The <xsl:text> element is used to write literal text to the output. Tip: This element may contain literal text, entity references, and #PCDATA.

Is XSLT 2.0 backward compatibility?

The XSLT 2.0 engine is backwards compatible. The only time the backwards compatibility of the XSLT 2.0 engine comes into effect is when using the XSLT 2.0 engine to process an XSLT 1.0 stylesheet.

How do you translate in XSLT?

translate( ) is a versatile string function that is often used to compensate for missing string-processing capabilities in XSLT. Here you use the fact that translate( ) will not copy characters in the input string that are in the from string but do not have a corresponding character in the to string.

What is number () in XSLT?

Specifies the format pattern. Here are some of the characters used in the formatting pattern: 0 (Digit)


3 Answers

You take the date 1970-01-01T00:00:00 and add as many milliseconds as the value of the stamp tells you:

<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>
like image 130
f3lix Avatar answered Oct 26 '22 10:10

f3lix


If you are using an XSLT 1.0 processor which supports the EXSLT date functions (I've just tested this with libxslt in PHP), you can use date:add() and date:duration():

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

The date:duration() function takes a number of seconds (so you have to divide your milliseconds by 1000) and turns it into a "duration" (in this case, "P14315DT20H12M26.6889998912811S"), which is then added to the start of your epoch (looks like the standard epoch, for this stamp) with date:add() to get a stamp of "2009-03-12T20:12:26.6889998912811Z". You can then format this using the EXSLT date functions or just substring(), depending on what you need.

like image 38
Ben Blank Avatar answered Oct 26 '22 10:10

Ben Blank


Belated answer, yes, I know, but I couldn't find the one I was looking for here, so I thought I'd pay it forward with my solution.

My XML was a few nodes dumped from Drupal using export_node and drush. I was using the xslt processor in PHP5, which only supports xslt 1.0. Some EXSLT functions appear to be supported, but I couldn't tell whether my syntax was wrong or the function I was trying to use was not supported. Anyway, the following worked for me. I used the example code from w3schools.com, but added a line right after declaring the xsltprocessor, like below:

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

PHP has a trivial function for date conversion, so I cheated and used the PHP processor, since I was already using it to transform my xsl.

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

Hope this helps someone out there. I was banging my head for quite a while as I worked this one out.

like image 31
Michael Avatar answered Oct 26 '22 09:10

Michael