Login

Extended Seconds-to-Duration Template Tag

Author:
gregorvolkmann
Posted:
October 31, 2014
Language:
Python
Version:
1.7
Score:
0 (after 0 ratings)

Extended Template Tag initially created by Dan Ward (http://d-w.me): https://djangosnippets.org/snippets/1398/

The default setting has been renamed to normal, output stays the same. If you have used the old tag with ':short' you have to remove or rename it to ':normal' for the same ouput!

As an example, given the duration 84658:

Short: 23:30:58 Normal (default): 23 hrs 30 mins 58 secs Long: 23 hours, 30 minutes and 58 seconds

Best regards,

Gregor Volkmann

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# Import template library
from django import template

# Set register
register = template.Library()

# Register filter
@register.filter
def sectodur(value, arg = 'normal'):

    """
    #######################################################
    #                                                     #
    #   Seconds-to-Duration Extended Template Tag         #
    #   Dan Ward 2009 (http://d-w.me)                     #
    #                                                     #
    #   modified:                                         #
    #   Gregor Volkmann 2014 (http://gregor.volkmann.me)  #
    #                                                     #
    #######################################################

    Usage: {{ VALUE|sectodur[:'short' | :'normal' | :'long'] }}
    Default: :'normal'

    NOTE: Please read up 'Custom template tags and filters'
          if you are unsure as to how the template tag is
          implemented in your project.
    """

    # Place seconds in to integer
    secs = int(value)
    # If short string is enabled
    if arg == 'short':

        # Set short names
        dayUnitName = ':'
        hourUnitName = ':'
        minUnitName = ':'
        secUnitName = ''

        # Set short duration unit splitters
        splitterSplitter = ''
        lastDurSplitter = ''
        nextDurSplitter = lastDurSplitter
        dayPluralizeString = ''
        hourPluralizeString = ''
        minPluralizeString = ''
        secPluralizeString = ''
        padZero = '0'
        noDurMessage = '0'

    # If short string is enabled
    if arg == 'normal':

        # Set short names
        dayUnitName = ' Tag'
        hourUnitName = ' Std'
        minUnitName = ' Min'
        secUnitName = ' Sek'

        # Set short duration unit splitters
        splitterSplitter = ' '
        lastDurSplitter = splitterSplitter
        nextDurSplitter = lastDurSplitter
        dayPluralizeString = ''
        hourPluralizeString = ''
        minPluralizeString = ''
        secPluralizeString = ''
        padZero = ''
        noDurMessage = 'Keine Dauer'

    # If normal string is enabled or no mode set
    if arg == 'long':

        # Set long names
        dayUnitName = ' Tag'
        hourUnitName = ' Stunde'
        minUnitName = ' Minute'
        secUnitName = ' Sekunde'

        # Set long duration unit splitters
        splitterSplitter = ' '
        lastDurSplitter = ' und '
        nextDurSplitter = ', '
        dayPluralizeString = 'e'
        hourPluralizeString = 'n'
        minPluralizeString = 'n'
        secPluralizeString = 'n'
        padZero = ''
        noDurMessage = 'Keine Dauer'

    # If seconds are greater than 0
    if secs > 0:

        # Import math library
        import math

        # Place durations of given units in to variables
        daySecs = 86400
        hourSecs = 3600
        minSecs = 60

        dayPadZero = ''

        # Create string to hold outout
        durationString = ''

        # Calculate number of days from seconds
        days = int(math.floor(secs / int(daySecs)))

        # Subtract days from seconds
        secs = secs - (days * int(daySecs))

        # Calculate number of hours from seconds (minus number of days)
        hours = int(math.floor(secs / int(hourSecs)))

        # Subtract hours from seconds
        secs = secs - (hours * int(hourSecs))

        # Calculate number of minutes from seconds (minus number of days and hours)
        minutes = int(math.floor(secs / int(minSecs)))

        # Subtract days from seconds
        secs = secs - (minutes * int(minSecs))

        # Calculate number of seconds (minus days, hours and minutes)
        seconds = secs

        # If number of days is greater than 0
        if days > 0:
            if arg == 'short':
                if days < 10:
                    dayPadZero = 2*padZero
                if days < 100:
                    dayPadZero = padZero

            # Add multiple days to duration string
            durationString += splitterSplitter + dayPadZero + str(days) + dayUnitName + (days > 1 and dayPluralizeString
 or '')

        # Determine if next string is to be shown
        if hours > 0:

            # If there are no more units after this
            if minutes <= 0 and seconds <= 0:

                # Set hour splitter to last
                hourSplitter = lastDurSplitter

            # If there are unit after this
            else:

                # Set hour splitter to next
                hourSplitter = (len(durationString) > 0 and nextDurSplitter or '')

        # If number of hours is greater than 0
        if hours > 0:

            # Add multiple days to duration string
            durationString += hourSplitter + splitterSplitter + (hours < 10 and padZero or '') + str(hours) + hourUnitName + (hours > 1 and hourPluralizeString
 or '')

        # Determine if next string is to be shown
        if minutes > 0:

            # If there are no more units after this
            if seconds <= 0:

                # Set minute splitter to last
                minSplitter = lastDurSplitter

            # If there are unit after this
            else:

                # Set minute splitter to next
                minSplitter = (len(durationString) > 0 and nextDurSplitter or '')

        # If number of minutes is greater than 0
        if minutes > 0:

            # Add multiple days to duration string
            durationString += minSplitter + splitterSplitter + (minutes < 10 and padZero or '') + str(minutes) + minUnitName + (minutes > 1 and minPluralizeString
 or '')

        # Determine if next string is last
        if seconds > 0:

            # Set second splitter
            secSplitter = (len(durationString) > 0 and lastDurSplitter or '')

        # If number of seconds is greater than 0
        if seconds > 0:

            # Add multiple days to duration string
            durationString += secSplitter + splitterSplitter + (seconds < 10 and padZero or '') + str(seconds) + secUnitName + (seconds > 1 and secPluralizeString
 or '')

        # Return duration string
        return durationString.strip()

    # If seconds are not greater than 0
    else:

        # Provide 'No duration' message
        return noDurMessage

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 7 months ago

Comments

Please login first before commenting.