clock image from

Formatting Time Durations in Tableau

This post was updated on 24 July 2015 to include additional details on applying the custom formatting calculation to aggregates.

Here’s a quick lunchtime post on working with durations in Tableau. By duration, I mean having a result that is showing the number of seconds, minutes, hours, and/or days in the form of dd:hh:mm:ss. This isn’t quite a built-in option, there are a several ways to go about this:

  • Use any duration formatting that is supported in your data source, for example by pre-computing values or using a RAWSQL function.
  • Do a bunch of calculations and string manipulations to get the date to set up. I prefer to avoid these mainly because they can be over 1000x slower than numeric manipulations. If you want to see how to do this, there’s a good example on this Idea for Additional Date Time Number Formats. (If that idea is implemented and marked as Released, then you can ignore this post!)
  • If the duration is less than 24 hours (86400 seconds), then you can use Tableau’s built-in date formatting. I’ll show how to do this here.
  • Do some calculations and then use Tableau’s built-in number formatting. This is the brand-new solution and involves a bit of indirection.

Durations Guaranteed To Be Less Than 24 Hours: Tableau’s Date Formatting

If you know your duration is always going to be less than 24 hours (86400 seconds), , then you can take advantage of Tableau’s built-in date formatting. The first step is to get your duration in seconds, if it’s not already. For example, for looking at the duration between two dates you can use DATEDIFF(‘second’,[Start Time], [End Time]). Once you have that number of seconds, then you can use the following calculation

If the total time is less than 24 hours, then we can use the following calculation: DATETIME([Seconds]/86400). Then we can use Tableau’s date format to set the format as hh:nn:ss (in this case hh:mm:ss will also work):

2014-07-30 13_32_56-Tableau - duration formatting

Here’s a view…take a look at what happens at 86400 seconds and beyond:

2014-07-30 13_27_39-Microsoft PowerPoint - [Presentation1]

Instead of showing 24 hours, the date formatting looks just at the hours, minutes, and seconds. As long as your duration is less than 86400 seconds, everything will be simple using this technique.

Any Duration: Using Arithmetic and Number Formatting

Though Tableau’s built-in formatting is not as powerful as Excel, we can still do quite a bit. Check out Robert Mundigl’s Custom Number Formats for a pretty exhaustive list of what can be done. (He’s also got a fantastic post on String Calculations that is worth checking out.)

For example, we can set up a custom number format of 00:00, and that will perfectly format a number as a time…up to 59 seconds, that is:

2014-07-30 13_42_26-Tableau - duration formatting


However, this is a clue to the next step, which is that since we space out numbers by colons, all we need to do is get the right value into the right decimal place. So, for example, instead of 60 seconds (1 minute) being a value of 60, it has to have a value of 100 so the 00:00 formatting will make it 01:00. Here’s a formula that does just that for mm:ss values:

//replace [Seconds] with whatever field has the number of seconds in it
//and use a custom number format of 00:00:00:00 
//(drop the first 0 to get rid of leading 0's for minutes)
IIF([Seconds] % 60 == 60,0,[Seconds] % 60)// seconds
+ INT([Seconds]/60) * 100 //minutes
In this formula, [Seconds] is a record-level field. In order for the calculation to work accurately in some situations (such as using it with Subtotals and Grand Totals) you’ll need to change [Seconds] to SUM([Seconds]) or some already-aggregated calculated field. –added 2014-12-22 per notes in the comments.

The formula uses the % (modulo) function to divide the number of seconds by 60 to get the remainder, the IIF statement is there to deal with what happens when the number of seconds is divisible by 60, the result of that is the number of seconds, then the number of minutes *100 is added to that. Here’s a view:

2014-07-30 13_46_12-Tableau - duration formatting


For hh:mm:ss the formula gets a little more complex. Just as the seconds had to be transformed to make 0-59 seconds, minutes have to do a similar transformation:

//replace [Seconds] with whatever field has the number of seconds in it
//and use a custom number format of 00:00:00 (drop the first 0 to get rid of leading 0's for hours)
IIF([Seconds] % 60 == 60,0,[Seconds] % 60)// seconds
+ IIF(INT([Seconds]/60) %60 == 60, 0, INT([Seconds]/60) %60) * 100 //minutes
+ INT([Seconds]/3600) * 10000 //hours

And for dd:hh:mm:ss there’s yet another transformation to convert hours to 0-23:

//replace [Seconds] with whatever field has the number of seconds in it
//and use a custom number format of 00:00:00:00 (drop the first 0 to get rid of leading 0's for days)
IIF([Seconds] % 60 == 60,0,[Seconds] % 60)// seconds
+ IIF(INT([Seconds]/60) %60 == 60, 0, INT([Seconds]/60) %60) * 100 //minutes
+ IIF(INT([Seconds]/3600) % 24 == 0, 0, INT([Seconds]/3600) % 24) * 10000 //hours
+ INT([Seconds]/86400) * 1000000 // days

Here’s a view showing all three calculations:

2014-07-30 13_53_37-Tableau - duration formatting

A little dose of math, sprinkle some custom number formatting on it, and voila, there’s some usable duration formatting. If you wanted to keep going into weeks then there would need to be another level of calculation, to get into months and years I’d probably use a different approach because the intervals (month lengths and year lengths) aren’t fixed.

Here’s the workbook on Tableau Public: Duration Formatting

If this is useful to you, or you have an alternative technique, let me know in the comments below!

Addendum on Aggregation (July 2015)

Some people people using this technique have run into problems as seen in the comments below and on the Tableau forums. For example, if we build a view like this and sum up all the values of Seconds with the duration calc applied (see the SUM() aggregation) the numbers don’t add up. In this view the total time in mm:ss should be 44558:00 but it’s showing up as 44554:80, a non-sensical amount:

Alternatively, if we keep Seconds in the view as a dimension but add a Grand Total, the Grand Total isn’t adding up either:

The issue is with regards to order of operations. When we build the views with the grand total or by summing the measure, there’s an aggregation happening and it’s not happening at the right time vis-a-vis the formatting. I put together a series of graphics to explain what is going on.

In the original post the duration calculations are performed for each record and the results are treturned from the view. So it looks like this:

So in this case here’s what’s going on under the hood:

That’s not often used in practice, more often a view looks like this, where the mm:ss is being used as a measure and then when the original calculation is brought into the view we can see that Tableau is actually aggregating the duration calculation with the default aggregation of SUM():

However, that SUM() has no effect because the level of detail (the granularity) of the view is the same is the same as the data — in other words, the view is effectively displaying the raw data. So the order of operations is actually like this:

So even though these two views look exactly the same, under the hood they are using two different ways to get there. Where this causes problems is when we apply an aggregation that is across multiple records or in a grand total or subtotal. The duration calculation that was meant to be applied to the final result is being applied to every record and it’s that transmogrified amount that is getting summed:

The solution is pretty straightforward, we just need to do the aggregation *before* we apply the duration calculation. So instead of the [Seconds] of the original calculation we use Sum Seconds with the formula SUM([Seconds]), and the formula for mm:ss (agg) is:

//replace [Sum Seconds] with whatever field has the number of seconds in it
IIF([Sum Seconds] % 60 == 60,0,[Sum Seconds] % 60)// seconds
+ INT([Sum Seconds]/60) * 100 //minutes

So the order of operations is now:

And here’s a view showing the inaccurate and now accurate aggregate calculations:

And a grand total:

I’ve updated the Duration Formatting workbook to reflect this addendum.

33 thoughts on “Formatting Time Durations in Tableau

  1. Dave Walp

    Wow! I know I will get a lot of use out of this. Thank you for your massive contributions to the community.

  2. Bobby Weaver

    Great information. I’ve already pasted the posting into Evernote for safe keeping. The only tidbit I would add is that your % (modulo) function formula also supports the hh:mm format as long as you specify ‘minute’ in the DATEDIFF formula.

  3. Pingback: Time Duration in Tableau | Data Knight Rises

  4. Bryan Andrews

    I have used the formula with success in calculating total Utilization hours for our ambulance units. Now the manager wants the format of the number to change. Basically he wants to see a whole number for the hours and the minutes and seconds shown as a decimal. In other words 198:22:15 becomes 198.37. Can I modify the formula to get that alternate format?

  5. Sabree

    I wanted to get your thoughts and advice on how to handle “drive times” from certain zip codes in Tableau. I’ve been searching around for some examples of this and haven’t found any yet. Thanks

  6. Hrvoje

    Thank you for the post Jerremy. But when I tried to aggregate values I had something like 23:80:10. To seconds are more than sixty. Is there any fix for that ?

    1. Jonathan Drummey Post author

      Hi Hrvoje,

      I’m Jonathan, not Jerremy. :) Without seeing your calc, I can’t help you. Try posting a packaged workbook with some sample data to the Tableau forums, then link back to it here and I’ll take a look.


  7. Pingback: Tinkering with FLOAT() and Durations « Tableau Tinkering

  8. Aleksandar

    Hello everyone,

    I’ve tried:

    For hh:mm:ss the formula gets a little more complex. Just as the seconds had to be transformed to make 0-59 seconds, minutes have to do a similar transformation:

    //replace [Seconds] with whatever field has the number of seconds in it
    //and use a custom number format of 00:00:00 (drop the first 0 to get rid of leading 0’s for hours)
    IIF([Seconds] % 60 == 60,0,[Seconds] % 60)// seconds
    + IIF(INT([Seconds]/60) %60 == 60, 0, INT([Seconds]/60) %60) * 100 //minutes
    + INT([Seconds]/3600) * 10000 //hours

    But as result I get, for example 11:98:56….
    I don’t no what I did wrong.

    If anyone knows what is the problem please post it.


    1. Jonathan Drummey Post author

      Hi Aleksandar, is that the exact calculation you are using in your workbook? It looks like you copied and pasted the text from the blog post, so I can’t be sure. Also, are you looking at a value in a detail row or a Grand Total? Grand Totals introduce an additional complication where you have to use an aggregate measure for the seconds in place of a record-level of seconds. What would make it easiest for me to help you is if you posted a link to either a Tableau Public viz or a Tableau packaged workbook file that the calc and some sample data.


  9. Aleksandar

    Hi Jonathan,

    I’ve copied an pasted the text and replace [Seconds] with my measure [total_talk_time] which is in seconds (ex.15456).
    I have a thousands of agents with different talk time and I want to see total of talk time in one month per agent but in format hh:mm:ss(but I have examples where there is overlap of 24 hours). I am very familiar with tableau but I dont exactly understand this calculation and therefore i dont know if i need to change something more.

    Thank you.

    1. Jonathan Drummey Post author

      This is a follow-up, Aleksandar and I had a conversation over email. The solution turned out to be using an aggregate calculation in place of [Seconds] in the calculation, I’ve added a note to that effect above.

  10. Pingback: Tableau Tips,Tricks,Best Practices - Formatting - Jenny (Xiao) Zhang

  11. ashok

    Hi Jonathan,

    This is super. But my scenario requires me to aggregate the time and it does not work with that. if i sum it up this gives me values like 01:70: 32:79. Please explain if there is any way to overcome this issue.

  12. Rody Zakovich

    Hello Jonathan,

    Thank you for pointing this out in the Forum. This is a fantastic workaround to a problem that I did not think was possible (Showing Duration in Measure Values)

    Love your blog and everything you do for the community!


    1. Jonathan Drummey Post author

      Hi Erik,

      Please see the worksheet in the Duration Formatting workbook. If you’re starting with seconds you have to make a choice about rounding seconds to minutes, the worksheet has calculations for both. The worksheet shows hh:mm calcs, to change them to h:mm all you need to do is use a custom format of #:##. Let me know if you have any more questions!


      1. Anita

        Hi ,

        I have a date field which give total duration spent by a person on particular task. The hour field has values lik , ” 0:45 : 34″ , ” 99:30:00″ , “203:56:45” etc. When I drag the filed to tableau , it shows data with date which converts the hours to below 23 number.

        I want to extract the total hours for a participant in hours. How Can I do that ?

        Say for “99:30:00” = 99.5 hours.


        1. Jonathan Drummey Post author

          Hi Anita,

          Since Tableau doesn’t have a built-in notion of duration it automatically interprets those fields as dates as you’ve discovered. In order for to convert the h:mm:ss duration into a decimal number of hours we need to do some string manipulation. Here’s a formula that works on most data sources using the FINDNTH() function introduced in Tableau v9. If you are on a data source that doesn’t support FINDNTH() that could be replaced with a combination of LEFT() and LEN(). There’s likely a regex-based solution as well.

          //assumes a duration string of format h:mm:ss where 34 seconds is 0:00:34 return the decimal number of hours
          INT(LEFT([myField], FIND([myField],’:’)-1))
          // minutes turned into hours
          + INT(MID([myField], FIND([myField],’:’)+1, FINDNTH([myField],’:’,2) – FIND([myField],’:’) – 1)) / 60
          // seconds turned into hours
          + INT(RIGHT([myField], 2)) / 3600


          1. Anita

            Thank you Jonathan. The actual problem with my data was Tableau converting the hours >24 to days automatically, that’s why I was not able to get the correct Hours from Date field by datepart function. Now I have converted the days also to hours to get correct total hours.

  13. mdeutschmtl

    Another hat tip from up on Montreal… I had to depict large numbers of elapsed seconds as ‘hh:mm:ss’ and found this very clear and well explained. Thanks, Jonathan! :)

  14. Don Wise

    Hi Jonathan,
    Thank you for the work here; it’s great! I think it’s resolving my issue with supplying a “dd” format to my data, but I’m seeing an issue with my results. We’re using Tableau to produce monthly reports for our local Fire Departments.

    Normally we only deal with incident durations of less than 24 hours so our results have never been in question. However, now we’re in need of determining an ambulance and fire engine total duration compared to the number of incidents they respond on each month. So we’re entering into a need to compute in a “dd:hh:mm:ss” format.

    For the majority of the units incident duration being measured, it looks good. But two of them that have less than 100 incidents per month are resulting in the following result(s): Engine 38 = 31:00:35:42 and Engine 39 = 30:19:48:28

    I’ve tried removing “/86400” from my original Incident Duration calc in order to use just the resulting record level decimal number and then used your formula separately for formatting, but achieved even stranger results. Is it possible our date formats that we’re using are differently structured?

    Thoughts? And thanks in advance for any insight…Don


Please add your thoughts and perspectives