2

I'm not asking a question actually. I signed up stackoverflow to give something back to a community that has helped me so many times.

If you are using XSLT 1.0 there are no built-in time calculations. I came up with this to convert seconds into minutes and hours. I hope this helps someone!

<xsl:template name="format-duration">
  <xsl:param name="value" />

  <xsl:variable name="minutes" select="floor($value div 60) mod 60" />
  <xsl:variable name="seconds" select="$value mod 60" />
  <xsl:variable name="hours" select="floor($value div 3600)" />


  <xsl:if test="$hours">
    <xsl:if test="$hours &lt; 10">
      <xsl:text>0</xsl:text>
    </xsl:if>
    <xsl:value-of select="$hours" />

    <xsl:text>:</xsl:text>
  </xsl:if>


  <xsl:if test="$minutes">
    <xsl:if test="$minutes &lt; 10">
      <xsl:text>0</xsl:text>
    </xsl:if>
    <xsl:value-of select="$minutes" />
    <xsl:text></xsl:text>
  </xsl:if>

  <xsl:if test="$minutes and $seconds">
    <xsl:text>:</xsl:text>
  </xsl:if>

  <xsl:if test="$seconds">
    <xsl:value-of select="$seconds" />
    <xsl:text></xsl:text>
  </xsl:if>
</xsl:template>

EDIT: Do you have any other methods to achieve the same?

Rookie Programmer Aravind
  • 11,952
  • 23
  • 81
  • 114
Neil Diamond
  • 21
  • 1
  • 3
  • 1
    Please ask the question and answer it yourself. It's okay to accept your own answers :) – wst Mar 12 '13 at 19:21
  • 1
    You actually mean "seconds to duration". And why stop at hours? What about days, and weeks? I know that months and years are much more challenging, but why not try these too? Finally, it seems like an unnecessary investment of effort -- much better use the date-time arithmetic available in XPath 2.0 (and XSLT 2.0). – Dimitre Novatchev Mar 13 '13 at 02:44
  • 1
    Rather than post the solution in the question, create a question and post the solution as an answer. Self answering is allowed (even encouraged). – ChrisF Mar 13 '13 at 09:37
  • I agree with Dimitre, You can make use of external processors like Saxon from your host to achieve XSLT 2.0 .. You don't have to struggle so much with XSLT 1.0. And exslt is an extension to xslt 1.0 which was created in 2001 itself .. try this link http://www.exslt.org/date/index.html – Rookie Programmer Aravind Mar 13 '13 at 15:54
  • Thanks for the input everyone. I've never posted on here before (longtime lurker). It is great to see some improvements. By the way, I know XSLT 2.0 can handle time, but I couldn't use that for some dumb reasons with what I was doing. I figured someone somewhere would run into something like this as well. I wish I could use 2.0 for a lot of things. Thanks! ;) – Neil Diamond Feb 28 '14 at 18:43

2 Answers2

6

Firt of all, thank you for your contribution. There are, however, a few issues with this implementation. The seconds output doesn't take the leading 0 into account, but even if that's fixed, the output can be ambiguous if any of the figures happens to be 0. For example, the inputs 36005, 605, and 36300 all produce the result 10:05.

Likewise if two of the figures happen to be zero. The input 36000 produces the output 10:, and the inputs 600 and 10 both produce the result 10.

Here is how I would go about implementing this functionality:

  <xsl:template name="format-duration">
    <xsl:param name="value" select="." />
    <xsl:param name="alwaysIncludeHours" select="false()" />
    <xsl:param name="includeSeconds" select="true()" />

    <xsl:if test="$value > 3600 or $alwaysIncludeHours">
      <xsl:value-of select="concat(format-number($value div 3600, '00'), ':')"/>
    </xsl:if>

    <xsl:value-of select="format-number(floor($value div 60) mod 60, '00')" />

    <xsl:if test="$includeSeconds">
      <xsl:value-of select="concat(':', format-number($value mod 60, '00'))" />
    </xsl:if>
  </xsl:template>

This way, hours are only displayed if they are non-zero or optionally turned on, and seconds are included by default, but can be optionally omitted by using the parameter values. This should reduce the ambiguity about what a time is supposed to represent.

It also allows omitting the value parameter if the value you want to format is the current context node.

JLRishe
  • 99,490
  • 19
  • 131
  • 169
3

Converting number of seconds to time (HH:MM:SS) in XSLT 1.0:

<xsl:template name="seconds-to-time">
    <xsl:param name="seconds"/>
    <xsl:variable name="h" select="floor($seconds div 3600)"/>
    <xsl:variable name="m" select="floor($seconds div 60) mod 60"/>
    <xsl:variable name="s" select="$seconds mod 60"/>

    <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:template>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51