Skip to Main Content

Twig Macro convert seconds to hh:mm:ss and reverse

I'm working out the last bit of front end work on the podcast I am launching shortly called Website 101 Podcast. On the front end of the site I want to output the length of each episode in human readable form like 47:24 However itunes requires your feed to have the <itunes:duration> in seconds.

Instead of having two fields for episode length, one seconds and the other human readable, I created a simple macro that does this for me.

    
      {% macro secondsToMinutes(seconds) %}
 
  {# set hours minus minutes/seconds #}
  {% set hours = seconds / 3600 % 60 %}

  {% if hours  < 1 %}
    {# set hours to nothing #}
    {% set hours = null %}
  {% else %}
    {# output hours with a colon: #}
    {% set hours = hours|number_format ~ ':' %}
  {% endif %}
  
  {# set minutes remain but no seconds and with a colon #}
  {% set minutes = seconds / 60 % 60  ~ ':' %}

  {# set seconds but no minutes or hours #}
  {% set seconds = seconds % 60 %}
  {% if seconds < 10 %}
    {# add a leading zero if seconds are less than 10 #}
    {% set seconds = '0' ~ seconds %}
  {% endif %}

  {{ hours }}{{ minutes}}{{ seconds }}

{% endmacro %}
    
  

The episodes in my podcast should be shorter than an hour. But just in case they go long I made sure that the macro will output hours as well.

In the template where you want your human readable time you place the following code where entry.showTime is the craft fieldname I used. This will convert 2844 to 47 minutes and 24 seconds like this 47:24

    
      {{ macros.secondsToMinutes(entry.showTime) }}
    
  

And The Reverse

After working with this for a little bit, I realized that when looking at the MP3 files I have for the podcast I can immediately see the hh:mm:ss but not complete seconds and had to manually convert to seconds in order to fill out the publish screen. This wasn't saving me any work. So now I've created another macro to reverse the process.

In my front end templates I'll use {{ entry.showTime }} and display what I type in the field. However in my RSS template I'll do the following

    
      {% macro timeToSeconds(time) %}
{# use spaceless to remove any whitespace #}
{% spaceless %}
  {# if time is less than 1 hour i.e. 45:17 #}
  {% if time|length > 5 %}

      {% set hours = time|split(':')[0] %}
      {% set minutes = time|split(':')[1] %}
      {% set seconds = time|split(':')[2] %}

  {% else %}
  {# time is longer than 1 hour i.e. 1:12:32 #}
      {% set hours = "0" %}
      {% set minutes = time|split(':')[0] %}
      {% set seconds = time|split(':')[1] %}
  {% endif %}
  
  {% set totalSeconds = (hours * 3600) + (minutes * 60) + seconds %}
    {{ totalSeconds }}
{% endspaceless %}
{% endmacro %}
    
  

And then in the RSS template use this:

    
      <itunes:duration>{{ macros.timeToSeconds(entry.showTime) }}</itunes:duration>