Andrew Sem
Andrew Sem

Reputation: 3

XSLT Convert milliseconds to timecode

Hello and have a nice day!

There are two steps that I'm trying to figure out:

  1. (But not in priority) to take integer from xml file with tag "duration" in milliseconds
  2. I am trying to convert "duration" milliseconds into timecode that will looks like hh:mm:ss:ff , where h - hours, m - minutes, s - seconds and f - frames (25frames=1second). As I see the algorithm is:
z=milliseconds
h=z idiv (60*60*25)
m=(z-h*60*60*25) idiv (60*25)
s=(z-h*60*60*25-m*60*25) idiv 25
f=(z-h*60*60*25-m*60*25-s*25)

Have any idea how to make a calculation within XSLT properly?

Upvotes: 0

Views: 335

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116992

Consider the following example:

XML

<input>
    <milliseconds>45045500</milliseconds>
</input>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:template match="input">
    <output>            
        <xsl:variable name="f" select="floor(milliseconds div 40) mod 25" />
        <xsl:variable name="s" select="floor(milliseconds div 1000) mod 60" />
        <xsl:variable name="m" select="floor(milliseconds div 60000) mod 60" />
        <xsl:variable name="h" select="floor(milliseconds div 3600000)" />
        <timecode>
            <xsl:value-of select="format-number($h, '00')"/>
            <xsl:value-of select="format-number($m, ':00')"/>
            <xsl:value-of select="format-number($s, ':00')"/>
            <xsl:value-of select="format-number($f, ':00')"/>
        </timecode>
    </output>
</xsl:template>

</xsl:stylesheet>

Result

<?xml version="1.0" encoding="UTF-8"?>
<output>
  <timecode>12:30:45:12</timecode>
</output>

Note that this truncates fractional frames. If you want to round to the nearest frame, then change the variables to:

        <xsl:variable name="totalFrames" select="round(milliseconds div 40)" />
        <xsl:variable name="f" select="$totalFrames mod 25" />
        <xsl:variable name="s" select="floor($totalFrames div 25) mod 60" />
        <xsl:variable name="m" select="floor($totalFrames div 1500) mod 60" />
        <xsl:variable name="h" select="floor($totalFrames div 90000)" />

Here the result will be:

<timecode>12:30:45:13</timecode>

In XSLT 2.0 or higher, you can shorten the expression floor($a div $b) to $a idiv $b.

Upvotes: 1

Related Questions