Wednesday, April 13, 2011

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.

From stackoverflow
  • XSLT is Turing complete, so there must be a way. :) Knowing at least a bit of XSLT, it will probably involve recursion.

    You don't specify the exact interpretation of your "ticks", I'm guessing milliseconds since some epoch, but which? 1970?

  • You take the date 1970-01-01T00:00:00 and add as many milliseconds as the value of stamp tell 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>
    
    Broam : How would one modify the answer to use the inner text in a node, instead of an attribute on it?
  • If you wanted to use an XSL 1.0 processor that does not support the EXSLT date and time functions this is non-trivial, but it has been done.

    You can have a look at Katy Coe's XSLT 1.0 implementation of the "iso-from-unix" function. It's part of a rather huge "free for non-commercial use" set of date and time functions she created.

    However, your XSL processor must support the "http://exslt.org/functions" namespace for this implementation to work. Other than that there is no dependency on EXSLT.

    P.S.: I'm aware that a Unix timestamp and ticks are not exactly the same thing. They are close enough, though.

  • 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.

0 comments:

Post a Comment