Everything in the same minute

Sunday 5 March 2006

The other day, I looked at a problem where we were displaying a list of things with dates and times. Although the times should have been spread out (it was an activity log), instead there would be many entries all at the same time:

Thing 1: 3/4/06 12:03
Thing 2: 3/4/06 12:03
Thing 3: 3/4/06 12:03

This looked familiar, and it became clearer when we looked at a larger sampling:

Thing 1: 3/4/06 12:03
Thing 2: 3/4/06 12:03
Thing 3: 3/4/06 12:03
Thing 4: 3/4/06 1:03
Thing 5: 3/4/06 2:03
Thing 6: 3/4/06 2:03
Thing 7: 3/4/06 3:03

Everything always happened at 3 minutes after the hour? That definitely wasn’t right. Then it hit me: I’d seen this exact bug at my last job. The times are being recorded properly, but displayed wrong, through a simple typo.

Date and time formatting is often done with a formatting string. The components of the date and time are indicated with prescribed letters: Y means a four-digit year, H means the hour in a 12-hour clock, and so on. The letters are chosen to be mnemonic, but of course there’s only so far you can take that without running out of letters, or colliding on mnemonics.

The problem at both workplaces was that instead of displaying minutes, we were displaying the month.

At the old job, we were using the .NET framework, so the date format string used M (numeric month with no leading zero) where it should have used m (minutes with no leading zero). The latest manifestation is in the Django framework, so the date format string used m (numeric month) where it should have used i (minutes).

At least this time I recognized it sooner.

Comments

[gravatar]
Calvin Spealman 5:00 PM on 5 Mar 2006

This is why I never liked subformats in anything. I prefer C++'s iostreams to C's printf, and I would prefer something that gets a binary structure from a python class than a string describing the format. Likewise, something like this would be much nicer:

MyFormatter = DateTimeFormat(
  Month(), DateSep(), DayOfMonth(), DateSep(), Year(leadzero=False),
  DateTimeSep(),
  Hour(hours=24), TimeSep(), Minute(leadzero=False)
)

Of course, all those special callables could just return string codes, and DateTimeFormat could just join all its arguments together into a formatting strings, but it would look nicer, be more understandable, and be far less prone to error.

[gravatar]
Manuzhai 6:22 PM on 5 Mar 2006

Well, too each his own, but I prefer my code a little more concise than that.

[gravatar]
Calvin Spealman 8:03 PM on 5 Mar 2006

Manuzhai: I don't consider 'i' as minutes to be very concise. Do you?

[gravatar]
Manuzhai 6:24 AM on 6 Mar 2006

It is very concise!! Just not very understandable. ;)

I always used to use YmdHi, though, so I remember those quite well. And in normal Python usage, the syntax would be %Y%m%d%H%M, which is even a little easier (though the difference is a little confusing).

[gravatar]
James Gray 7:08 PM on 10 Mar 2006

I'd prefer this syntax myself. It seems both clear and relatively concise:

datetime.format("$year $month $day $hour $minute")

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
URLs auto-link and some tags are allowed: <a><b><i><p><br><pre>.