# Scripting Data Source - Seconds to hh:mm:ss

**URL:** <https://forum.inductiveautomation.com/t/scripting-data-source-seconds-to-hhss/92634>\
**Category:** Ignition\
**Tags:** ignition81, scripting\
**Created:** [July 1, 2024, 3:34pm UTC](https://forum.inductiveautomation.com/t/scripting-data-source-seconds-to-hhss/92634 "2024-07-01T15:34:08Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fraser](https://avatars.discourse-cdn.com/v4/letter/f/6de8d8/32.png) [@Fraser](https://forum.inductiveautomation.com/u/Fraser)\
**Post date:** [July 1, 2024, 3:34pm UTC](https://forum.inductiveautomation.com/t/scripting-data-source-seconds-to-hhss/92634/1 "2024-07-01T15:34:08Z")

</div>

I have a data source using a Tag Historian Query with several boolean "Running" tags. My aim is to calculate running hours over a set time frame. I can do this using the "Duration On" aggregation mode but it gives me the result in seconds and I need this to display in hh:mm:ss format.

I believe the only way to achieve the result in hh:mm:ss format is by using a script data source but I am struggling to achieve the result. Any ideas?

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [July 1, 2024, 3:46pm UTC](https://forum.inductiveautomation.com/t/scripting-data-source-seconds-to-hhss/92634/2 "2024-07-01T15:46:51Z")

</div>

Logging runtimes seems like a job for the PLC, but as far as purely converting seconds to hh.mm/mm.ss, here is mine. I'm sure there's a more efficient way to do it, but this works for me.

```python
def toHHMMSS(val, hours, mins, secs):
    '''
    convert a value in hours, minutes, or seconds to a readable hours.minutes/minutes.seconds (hh.mm/mm.ss) format
    
    Args:
        val (double) : time value to convert
        hours (bool) : time value is in hours
        mins (bool) : time value is in minutes
        secs (bool) : time value is in seconds
        
    Returns:
        result (double : time to display
        result_label (string) : label for result (hh.mm or mm.ss))
    '''

    from math import floor
    
    ####convert any provided val to seconds####
    
    #value provided in seconds
    if secs:
        val_seconds = val
        
    #value provided in minutes
    elif mins:
        val_seconds = val*60.0
        
    #value provided in hours
    else:
        val_seconds = val*60.0*60.0
    
        
    ####hours calculation####
    
    #more than 1 full hour
    if val_seconds > 60*60:
        #calculate hours
        val_hours = val_seconds/(60.0*60.0)
        #get whole number of hours
        whole_hours = floor(val_hours)
        #get remaining number of minutes
        rem_minutes = (val_hours - whole_hours)*60.0
        
        #set whole and fractional results (hh.mm)
        result_whole = whole_hours
        result_rem = rem_minutes/100.0
        result_label = 'hh.mm'
    
    #less than 1 full hour
    else:
        ####minutes calculation####
        
        #more than 1 full minute
        if val_seconds > 60:
            #calculate minutes
            val_minutes = val_seconds/60.0
            #get whole number of minutes
            whole_minutes = floor(val_minutes)
            #get remaining number of seconds
            rem_seconds = (val_minutes - whole_minutes)*60.0
            
        #less than 1 full minute
        else:
            #no full minutes
            whole_minutes = 0
            #get remaining number of seconds
            rem_seconds = val_seconds
            
            
        #set whole and fractional results (hh.mm)
        result_whole = whole_minutes
        result_rem = rem_seconds/100.0
        result_label = 'mm.ss'
    
    #combine whole number with decimal
    result = result_whole+result_rem
    
    return result, result_label

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 1, 2024, 3:54pm UTC](https://forum.inductiveautomation.com/t/scripting-data-source-seconds-to-hhss/92634/3 "2024-07-01T15:54:44Z")

</div>

You could pair the above with something like this general purpose `mapColumn` function for datasets, to update all the values in a particular column of the dataset as one operation:

> [@Can I modify an entire column from a dataset with system.dataset.setValue()?](https://forum.inductiveautomation.com/t/can-i-modify-an-entire-column-from-a-dataset-with-system-dataset-setvalue/87043/3):
>
> def mapColumn(function, dataset, column): if isinstance(column, basestring): column = dataset.getColumnIndex(column) columnData = map(function, dataset.getColumnAsList(column)) columnsToKeep = range(dataset.columnCount) columnsToKeep.pop(column) dsWithoutColumn = system.dataset.filterColumns(dataset, columnsToKeep) return system.dataset.addColumn( dsWithoutColumn, column, columnData, dataset.getColumnName(column), dataset.getColumnType(column) ) It's relatively easy to…

You get less control over the boundary conditions, but you can also use our FormatUtil internal library to achieve the same result:

> [@OPC Tag Value Seconds to HH:MM:SS via Expression Tag](https://forum.inductiveautomation.com/t/opc-tag-value-seconds-to-hhss-via-expression-tag/45544/23):
>
> Not an expression, but another option would be to do this in a script library: from java.util import Locale from com.inductiveautomation.ignition.common import FormatUtil def formatTime(time): return FormatUtil.formatDuration(Locale.getDefault(), time, FormatUtil.DurationFormatStyle.COMPACT, False) \>\>\> formatTime(1123311123) u'13d 00:01:51' \>\>\> formatTime(1123311) u'00:18:43' \>\>\> formatTime(38460) u'00:00:38' \>\>\> formatTime(38460123) u'10:41:00'

---

<div class="post-metadata">

**Author:** ![amarks](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/amarks/32/45610_2.png) [@amarks](https://forum.inductiveautomation.com/u/amarks)\
**Post date:** [July 2, 2024, 3:04pm UTC](https://forum.inductiveautomation.com/t/scripting-data-source-seconds-to-hhss/92634/4 "2024-07-02T15:04:53Z")

</div>

Quick question.

This script returns two values, the float and a string label.  
How would I reference each using `runScript()` in an expression binding (if possible)?

edit: I was able to do it with `runScript(...)[0]` and [1]
