Rounding time to nearest 5 or 15 or 30 minutes

I know I can set up a Rule to do this, but is there a clever way of rounding time by minutes and hours?

I have timestamps for every minute of every day, and I’d like to be able to look at graphs where I group them into 5, 10, 15 and 30 mins and hourly chunks, as well as 3 and 6 hour chunks.

This will allow me to assess how important the actual minute is vs the general time.

I’d also like to be able to skew this so that if I’m looking at 10 minutes, it would be from 5 to the hour to 5 mins past the hour for example.

My times are in the format HH:mm.

Hi,

I always love a good date and time challenge! :slight_smile:

You mention your times are in the format “HH:mm” but not if they are stored as text or as proper numeric timestamps. Almost always we want the latter. Once we have numeric timestamps, just about everything we want to do with a date or time is then just math.

I wrote a whole series of posts on handling dates and timestamps in EasyMorph which you might want to read if you haven’t before. EasyMorph | Working with dates in EasyMorph - Part 1

The most important part for your questions is that dates are whole numbers and times are fractions of a day. So 06:00 is 0.25 of a day, 12:00 is 0.5 of a day, etc.

To “round” timestamps to a certain number of minutes, we can perform the following steps:

  • Multiply our timestamp by the number of “chunks” which fit in a day. So if our chunk size is 5 minutes, there are 288 chunks in a day (i.e. 1440/5 as there are 1440 minutes in a day)
  • We can then round down our result (A.K.A. floor).
  • And finally, divide that result by the same number of chunks

As long as your chunk size fits evenly within a day, this approach should work. You can of course make the chunk size a parameter to make it adjustable within your app.

Skewing the chunk starts adds a little complexity, but its just simple math on top of what we’ve done above. The steps are as follows:

  • Add to our timestamp the number of minutes we want to skew our chunks by. This needs to be a decimal value, so 5 mins would be 0.003472r (i.e. (1/1440)*5 )
  • Multiply result by the number of “chunks” which fit in a day.
  • We can then round down our result (A.K.A. floor).
  • Divide that result by the same number of chunks.
  • And finally, subtract the same decimal skew size we started by adding.

Here is a morph which shows all of the expressions used in the above examples:

timestamp_bucketing.morph (5.0 KB)

Hope this helps!

Regards
Matt

4 Likes

Hi Matt,

thank you, this is amazing.

I did a quick hack to get what I needed but this is far more robust and works with the source date/time - implementing it now!

Regards

Rish

Hi Rish

No problem at all, glad it works!

Regards
Matt