Reason #84 • March 25th, 2026

Time arithmetic

When dealing with time, it is quite common to want to advance or rewind a time by a certain amount. Ruby's Time class provides a convenient way to do this using the + and - operators, where the argument is the number of seconds to add or subtract:

Ruby
time = Time.new(2026, 3, 25, 12)
# => 2026-03-25 12:00:00 +0000

one_minute_earlier = time - 60
# => 2026-03-25 11:59:00 +0000

one_hour_later = time + 3600
# => 2026-03-25 13:00:00 +0000

two_days_later = time + 2 * 24 * 3600
# => 2026-03-27 12:00:00 +0000
      
JavaScript
const time = new Date(2026, 2, 25, 12);
// => Wed Mar 25 2026 12:00:00 GMT+0000

const oneMinuteEarlier = new Date(time.getTime() - 60 * 1000);
// => Wed Mar 25 2026 11:59:00 GMT+0000

const oneHourLater = new Date(time.getTime() + 3600 * 1000);
// => Wed Mar 25 2026 13:00:00 GMT+0000

const twoDaysLater = new Date(time.getTime() + 2 * 24 * 3600 * 1000);
// => Fri Mar 27 2026 12:00:00 GMT+0000
      

We can also pass other Time objects to the - operator to get the difference in seconds between them:

Ruby
started_at = Time.now

sleep 2

completed_at = Time.now

duration = completed_at - started_at
# => 2.00514
      
JavaScript
const startedAt = new Date();

setTimeout(() => {
  const completedAt = new Date();
  const duration = (completedAt.getTime() - startedAt.getTime()) / 1000;
  // => 2.00514
}, 2000);
      

Disclaimer: If you want precise duration measurements, e.g. for benchmarking purposes, you will get more precise results with Process.clock_gettime(Process::CLOCK_MONOTONIC) instead. But let's be real - that's way too many characters to type for a quick and dirty measurement!

History

Time arithmetic has been part of Ruby since its inception.

In terms of inspiration, it appears that Smalltalk had a similar concept of adding and subtracting seconds from time objects, which likely influenced Ruby's design. It didn't use + and - operators, though. Instead, it used named methods.

Common Lisp also has the concept of time arithmetic using seconds, but we end up working with time as regular integers, so it doesn't really feel the same.

Another close match to Ruby's approach could be found in Ada 83, where TIME and DURATION types could respond to + and - operators in a way that is quite similar to Ruby's. However, Ada usually isn't associated with influencing Ruby's design, so it's hard to say if it had any actual impact.

Reason #85 ?