Секунды к времени в XSLT

Я не задаю вопрос на самом деле. Я зарегистрировался в stackoverflow, чтобы отблагодарить сообщество, которое много раз мне помогало.

Если вы используете XSLT 1.0, встроенные вычисления времени отсутствуют. Я придумал это, чтобы конвертировать секунды в минуты и часы. Я надеюсь, что это помогает кому-то!

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

РЕДАКТИРОВАТЬ: Есть ли у вас другие способы добиться того же?


person Neil Diamond    schedule 12.03.2013    source источник
comment
Пожалуйста, задайте вопрос и ответьте на него сами. Это нормально, принимать свои собственные ответы :)   -  person wst    schedule 12.03.2013
comment
На самом деле вы имеете в виду секунды для продолжительности. А зачем останавливаться на часах? А дни и недели? Я знаю, что месяцы и годы гораздо сложнее, но почему бы не попробовать и это? Наконец, это кажется ненужным вложением усилий — гораздо лучше использовать арифметику даты и времени, доступную в XPath 2.0 (и XSLT 2.0).   -  person Dimitre Novatchev    schedule 13.03.2013
comment
Вместо того, чтобы публиковать решение в вопросе, создайте вопрос и опубликуйте решение как ответ. Допускается (даже поощряется) самостоятельный ответ.   -  person ChrisF    schedule 13.03.2013
comment
Я согласен с Димитре, вы можете использовать внешние процессоры, такие как Saxon, с вашего хоста для достижения XSLT 2.0. Вам не нужно так сильно бороться с XSLT 1.0. И exslt — это расширение для xslt 1.0, которое было создано в 2001 году. Попробуйте эту ссылку exslt.org /дата/index.html   -  person InfantPro'Aravind'    schedule 13.03.2013
comment
Благодарность за вклад каждого. Я никогда раньше не писал здесь (давний скрытник). Приятно видеть некоторые улучшения. Между прочим, я знаю, что XSLT 2.0 может работать со временем, но я не мог использовать его по каким-то глупым причинам для того, что я делал. Я думал, что кто-то где-то тоже сталкивался с чем-то подобным. Я хотел бы использовать 2.0 для многих вещей. Спасибо! ;)   -  person Neil Diamond    schedule 28.02.2014


Ответы (2)


Прежде всего, спасибо за ваш вклад. Однако есть несколько проблем с этой реализацией. Вывод секунд не учитывает начальный 0, но даже если это фиксировано, вывод может быть неоднозначным, если какая-либо из цифр равна 0. Например, входные данные 36005, 605 и 36300 дают результат 10:05 .

Аналогично, если две цифры равны нулю. Вход 36000 дает результат 10:, а входы 600 и 10 дают результат 10.

Вот как я бы реализовал эту функциональность:

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

Таким образом, часы отображаются только в том случае, если они не равны нулю или необязательно включены, а секунды включены по умолчанию, но могут быть дополнительно опущены с помощью значений параметров. Это должно уменьшить двусмысленность в отношении того, что должно представлять время.

Это также позволяет опустить параметр value, если значение, которое вы хотите отформатировать, является текущим узлом контекста.

person JLRishe    schedule 12.03.2013
comment
Мне пришлось изменить минуты на это: <xsl:value-of select="format-number(floor($value div 60), '00')" /> Большое спасибо, очень выручили меня ;) - person net.uk.sweet; 14.11.2013
comment
@net.uk.sweet Что произошло, когда вы попробовали мой подход? Вроде должно работать нормально. - person JLRishe; 19.11.2013
comment
Эта формула неверна: 90 секунд должны возвращать 01:30, а не 02:30. - person michael.hor257k; 13.02.2017
comment
@ michael.hor257k Исправлено. - person JLRishe; 13.02.2017

Преобразование количества секунд во время (ЧЧ:ММ:СС) в 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>
person michael.hor257k    schedule 13.02.2017