jessica dussault

There are 300 hours in each 5 minute day

Date
27 March, 2026
Category
code
Tags
Ruby on Rails

I hate working with dates and times. I learned to dislike them quite early in my programming career, when I got caught up trying to figure out a weird bug and ended up finding some code (happily, not the source of the bug) with a comment from coworker and bestie Wesley, who had written something along the lines of:

// this date function will need to be revisited in the year 2100 because it has no leap day 

As my friend John says, "if at any point working with dates you find yourself on the Wikipedia page for a pope, you should rethink what you're doing." Or maybe John was quoting someone else, like Abraham Lincoln. At any rate, they are words I live by.

Fortunately (?), I rarely get that far. In a way it's too bad, because I like reading about history on Wikipedia, even if I don't like thinking about dates. Yet, I'm usually still stuck trying to figure out if what I'm looking at is in UTC or my time zone or maybe the user's time zone, and that's all assuming I even managed to read whatever weird format into a library to begin with.

One thing I enjoy about Rails is that it has really nice built-ins for duration and easy date math. Where I might have once written

# hours * minutes * seconds
DURATION = 5 * 60 * 60

or similar to make it clear that the duration is 5 hours in seconds rather than just writing 18000 and making future devs do their own math, now I can simply write:

DURATION = 5.hours

Even better, I use the Rails date + duration functionality constantly, because I love writing things like this:

Time.current - 5.days

Heartbreak

Finally, my programming experience with dates was going well. You can imagine, then, how despondent I was to stumble across the following one day:

# makes sense
5.minutes
=> 5 minutes
5.minutes.seconds
=> 300 seconds

# makes less sense
300.seconds
=> 300 seconds
300.seconds.minutes
=> 300 minutes

# wat
5.minutes
=> 5.minutes
5.minutes.hours
=> 300 hours

This is about the point that one of my coworkers (yes, it was Wesley again), started philosophizing about the nature of time. But had we really discovered a new truth about our experiential plane, or was there something else going on?

What's happening

If we look at the ActiveSupport::Duration source code, we see the following. Warning -- a reference to a pope's name appears twice:

SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR   = 3600
SECONDS_PER_DAY    = 86400
SECONDS_PER_WEEK   = 604800
SECONDS_PER_MONTH  = 2629746  # 1/12 of a gregorian year
SECONDS_PER_YEAR   = 31556952 # length of a gregorian year (365.2425 days)

PARTS_IN_SECONDS = {
  seconds: 1,
  minutes: SECONDS_PER_MINUTE,
  hours:   SECONDS_PER_HOUR,
  days:    SECONDS_PER_DAY,
  weeks:   SECONDS_PER_WEEK,
  months:  SECONDS_PER_MONTH,
  years:   SECONDS_PER_YEAR
}.freeze

.seconds, .minutes, .hours, etc are simply taking some kind of integer / float / etc and then saying "calculate how many seconds this is using the above constants."

5.minutes
=> 5 minutes
5.minutes.to_i
=> 300

When you chain it with like 5.minutes.hours what's happening is that behind the scenes, 5.minutes gets passed to the next method as 300, which we understand to be seconds but it has no such context for .hours, which simply gets 300 and says "guess you wanted 300 hours."

What you're actually supposed to do

If only I had scrolled slightly further on the documentation page, I would have seen that there are methods made just for this use case!

20.minutes.in_hours
=> 0.3333333333333333

300.seconds.in_minutes
=> 5.0

What a relief! I can continue to live my life with Rails, unencumbered by having to spend my brainpower thinking about dates.