How many seconds are there in a minute? If you said 60, you’re wrong. Some minutes have 61, although the so-called leap second only comes around every few years, and then only once a year at most.

How many minutes in an hour? There are 60—at least, I can’t think of any cases when there are more or fewer. However, one of those minutes could have a leap second, giving a length of 3,600 or 3,601 seconds for an hour.

How many hours in a day? 24? Sometimes: it depends. With summer/winter time zone changes, it can be an hour longer or shorter, making 23, 24 or 25 hours. Allowing for the fact that a leap second may occur, that means that a day is in the range of 82,800 to 90,001 seconds long.

How many days in a month? In the Gregorian calendar, it can be 28, 29, 30 or 31 days. Allowing the minimum and maximum day lengths above, that’s somewhere between 2,415,600 and 2,678,401 seconds inclusive.

That’s not exhaustive, and I might have missed further complications, but the point of all this is simple: the precise length of any unit of time longer than a second is undefined. Minutes, hours, days, weeks, months and years only have a specific length within a particular time context.

Even then, it gets complicated. If we are currently in the 25th hour of an autumn day on which the clocks go back, what is the time this time tomorrow?

I was prompted by this plaintive message on the ruby-talk mailing list this morning, from someone bitten by a ‘daylight saving’ bug:

The Time::next_week method is supposed to give the time of the start of the next week. But look at this, it cocks up :

>> t=Time.parse "Monday October 16th 2006"
=> Mon Oct 16 00:00:00 BST 2006
>> t.next_week
=> Mon Oct 23 00:00:00 BST 2006
>> t.next_week.next_week
=> Tue Oct 24 00:00:00 BST 2006
>> t.next_week.next_week.next_week
=> Mon Oct 30 00:00:00 GMT 2006

Arrhhhgg!! Its just f*cked up my application data!

I feel his pain. Even if it’s hard to say how things should work in certain pathological cases, this doesn’t strike me as one of them. There is, by the way, an outstanding patch for this bug.

On the other hand, it’s fine to be blasé in certain situations. If I want to clear out cache files over a day old, I probably don’t care about a few seconds either way, so I’m going to be happy with 86,400 seconds (which is what 1.day will give me in Rails, for example).

The moral of the story? Use abstract lengths of time when accuracy is unimportant. When it matters, use methods that understand the context (as I mentioned previously)—and test those edge cases: the author of the code you’re using might not have thought of the problem, or might have interpreted it differently to you.