Thursday, February 28, 2008

A man lies and dreams of green fields and rivers

This winter has been the coldest and snowiest in Southern Ontario in a long time (at least as far as my memory goes - I haven't checked the stats). The wind chill this morning was -26C for the 6:00am dog walk. The snowbanks on our street are at shoulder level.

And yet, spring is just around the corner. Curling playoffs start next week. We've already booked four camping trips - Inverhuron in June, MacGregor Point in July, Grundy Lake in July and Presqu'ile in July/August. Two more to book yet - Algonquin in August and Long Point for the Labour Day long weekend.

Friday, February 22, 2008

Sex education comes to Woolwich Township?



Actually, no. It's a story about a watermain replacement, but that picture is just a little... unsettling, no?

I mean, c'mon, the guy's a Conservative Member of Parliament. Conservatives don't have sex. Certainly not with other men!

Besides, the sex education in Woolwich Township is under control. The driver's education folks get the car on Monday, Wednesday and Friday, and the sex-ed folks get it on Tuesday, Thursday and Saturday.

Thursday, February 21, 2008

Conversation of the day

On the heels of a warning that a "growing number of people are becoming addicted to their mobile phones, Blackberries and other digital devices," comes today's conversation:

Me: Jack, where's your blackberry?

Jack: I left it in the car.

Me: Doesn't that bother you, knowing it's sitting there, beeping and flashing? Calling out for you?

Jack: Ah, fuck it. I hate that fucking thing. I used to love it. Now I hate it.

TSN Broadband

Sat down to watch the Scotties last night, then remembered that TSN was showing it at 11:00, after the hockey game. Grabbed the laptop, borrowed the S-Video cable from the DVD player, and plugged 'er in. A little jerky from time-to-time, but overall a pretty good quality display. So good, in fact, that when my wife came in she asked me why the laptop was on the floor by the TV.

So, bad on you TSN for showing a hockey game when you could be showing a real sport, but good on you for at least letting us watch online. It was a pretty good game too, at least for the first five ends. Quebec sure doesn't get freaked out when the other team is lying two for most of the end. Two or three good shots by the vice and skip, and the next thing you know a 3 goes up on the scoreboard. Should have been a 4 though, which might have come in handy later in the game when some questionable strategy calls were made.

Sunday, February 17, 2008

Not a good thing to hear

This afternoon, the seven-year-old and the four-year-old are in the seven-year-old's room, cleaning out the closet.

From the living room, over the "greatest hits of the 80s" on the radio, and the Scotties on the TV, I hear the four-year-old yell, "HOLY CRAP, VERONICA!!!"

Turns out it was nothing, just some clothes falling in the closet, but still...

Friday, February 15, 2008

Red red wine

I heard a story on the radio this morning that said that one glass of red wine a day is good for your heart.

I haven't had any red wine at all this week, so I guess I'd better catch up and have seven glasses tonight.

Thursday, February 14, 2008

Time, keeps on slippin' slippin' slippin', into the future

Let's play the "feature or creature" game again. It works like this - I'll describe a software problem and we'll try to decide if the behaviour was intentional (a feature) or a bug (a creature).

Today's problem - a hospital in Italy has some software that doesn't like the Italian time format. Italy uses a period as the separator when time is displayed.



So they change the time separator from the default period (.) to a colon (:).



Now their software is happy. But ours isn't. We still display the original format.



And to make it worse, when we try to sort our table by date or time, we crash!

What's going on? There are a few things here. First of all, the crash happens because we're taking the time string (e.g., "8.41") and trying to turn it back into a DateTime, using Convert.ToDateTime(), and the format doesn't match. The Convert is expecting "8:41" and we've got "8.41".

We're displaying the time by using the .NET DateTime.ToShortTimeString() method. This doesn't pick up the change in the time separator. So I try using ToString() with the short time format from Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortTimePattern, but it has the same problem. What strike me as odd, though, is that the LongTimePattern does pick up the correct time separator. I'm going to vote "creature" on that one. I think the time separator should be reflected in both the Short and Long time patterns.

Anyway, it's not, so how do we get this to work? The ideal situation would be to display the time according to the user's customized short time format. That will also fix our crash. But ToShortTimeString() and ToString() don't work. Time to hit the Google. And we stumble upon Michael Kaplan's fine blog, where he tells us all about the problem in these posts.

So now we know what to do - use GetTimeFormat() to yank out the LongTimePattern, but ignoring the seconds. There's one other catch - sometimes we want to show the AM/PM marker, and sometimes we don't. In the case where we are using English (US), and the user has changed the time format to use the 24 hour clock, we'd prefer to show 18:00 instead of 18:00 PM. Anything to keep me out of Guantanamo Bay a little longer...

Here's the code:

/// <summary>

/// the user locale

/// </summary>

private const int LOCALE_USER_DEFAULT = 0x400;

 

/// <summary>

/// we don't care about seconds (we're trying to mimic the short time)

/// </summary>

private const int TIME_NOSECONDS = 0x2;

 

/// <summary>

/// leave off the AM/PM marker

/// </summary>

private const int TIME_NOTIMEMARKER = 0x4;

 

/// <summary>

/// the win32 SYSTEMTIME structure

/// </summary>

[StructLayout(LayoutKind.Sequential)]

    private struct SystemTime

{

    [MarshalAs(UnmanagedType.U2)]

    public ushort Year;

    [MarshalAs(UnmanagedType.U2)]

    public ushort Month;

    [MarshalAs(UnmanagedType.U2)]

    public ushort DayOfWeek;

    [MarshalAs(UnmanagedType.U2)]

    public ushort Day;

    [MarshalAs(UnmanagedType.U2)]

    public ushort Hour;

    [MarshalAs(UnmanagedType.U2)]

    public ushort Minute;

    [MarshalAs(UnmanagedType.U2)]

    public ushort Second;

    [MarshalAs(UnmanagedType.U2)]

    public ushort Milliseconds;

}

 

/// <summary>

/// formats time as a time string for the locale specified

/// </summary>

/// <param name="locale">the locale</param>

/// <param name="dwFlags">options</param>

/// <param name="time">the time information to format</param>

/// <param name="format">format picture to use to format the time string</param>

/// <param name="sb">a buffer in which this function retrieves the formatted time string</param>

/// <param name="sbSize">size of the buffer</param>

/// <returns>number of characters in the buffer</returns>

[DllImport("kernel32.dll")]

static extern int GetTimeFormat(uint locale, uint dwFlags, ref SystemTime time, string format, StringBuilder sb, int sbSize);

 

/// <summary>

/// format a time to a nice display time

/// </summary>

/// <param name="hour">hour</param>

/// <param name="minute">minute</param>

/// <param name="second">second</param>

/// <returns>nicely formatted time, according to the user's regional settings</returns>

public static string FormatTime(int hour, int minute, int second)

{

    // fill in the system time structure with the values we were given

 

    SystemTime systemTime = new SystemTime();

    systemTime.Hour = (ushort) hour;

    systemTime.Minute = (ushort) minute;

    systemTime.Second = (ushort) second;

 

    StringBuilder sb = new StringBuilder();

    sb.Append('\0', 64);

 

    // if we're using 24 hour time, leave off the AM/PM marker

 

    string pattern = Thread.CurrentThread.CurrentCulture.DateTimeFormat.LongTimePattern;

    uint flags = TIME_NOSECONDS;

 

    if (pattern.StartsWith("H"))

    {

        flags = TIME_NOSECONDS | TIME_NOTIMEMARKER;

    }

 

    GetTimeFormat(LOCALE_USER_DEFAULT, flags, ref systemTime, pattern, sb, sb.Length);

    return sb.ToString();

}



And finally, the finished product.

Busy, busy, busy

I've been doing some learnin' this week.

I've learned...

- how to send an XmlHttpRequest from javascript, vbscript and C#. Can't say I enjoyed it.

- how evil the DataSet can be. If you really think your application is too fast, throw some DataSets in. That'll fix it.

- that a hospital's IT department can be a little too smart for its own good. Case in point - IT department notices that one user's IsolatedStorage folder seems to work, and another's doesn't, so they blast the contents around the hospital to the other users. Suddenly, the application stops behaving properly. Just looking in an application's IsolatedStorage folder is like looking up its skirt. Knowing what's in there is like knowing how sausage is made. You don't want to be doing that.

- and finally, that sometimes big companies do the stupidest things.

Tell me, if you work for a company with under 100 people, would you demand that everyone on your development team take a product knowledge test, and that they pass with a > 70% score? If they fail too many times, lock them out, and track the success of the testing, so you know who hasn't taken the test, and who's failed it too many times? I thought not.

If your SuperMegaCorp does this sort of thing, can you tell me how this is going to increase sales, improve quality, or get the product out the door faster? I thought not.

Wednesday, February 06, 2008

Conestoga College is... closed?


What the heck? Closed?

Conestoga College has only closed due to bad weather three times in the last thirteen years. Now it's twice in four days?

Last year, the College got a ton of bad press for being the only thing open in the entire Region of Waterloo on a brutal freezing rain day. Did they take this to heart? For sure, last Friday was bad, and the school should have been closed. But today? C'mon, the elementary schools are open.

I wonder if this has anything to do with the fact that students are scoring the College on the Key Performance Indicators this week. Angry students don't lead to being the number one College in Ontario ten years in a row...

Monday, February 04, 2008

Ontario Tankard

I see lots of traffic coming in looking for Tankard information, so here are some helpful links for those of you looking for details on the Ontario Men's Curling Championship underway in Waterloo this week:

And then one day you find, ten years have got behind you

Ten years. I've been a SuperMegaCorp employee for ten years. How did that happen?

To be fair, it hasn't always been SuperMegaCorp. In the Before Time, things were different. We worked a lot of nights and some weekends. We spent many all-nighters in hospitals, roaming the building, installing new versions of the software by hand. This was the days before automatic updates became, well, automatic.

We just don't do that anymore. Partly that's a reflection of how mature the software has become - it just doesn't need us to do that anymore. It's also partly a desire to see proper recognition given to those who deserve it. We used to be the Marines of software development - first ones in, work hard, get 'er done, last ones out. We did it because the hospital needed us to, or because the software was missing something. Now, if we need to resort to that, it's because someone fucked up. Someone lied to their boss about how fast things were going to get done, or a project plan was a fantasy, or the guys on the front line installed and ran. The folks around here just don't have the stomach for covering that up.

Can I see myself here in another ten years? Probably not, but I didn't think I'd last this long, so you never know. Rumour has it that the "longevity rewards" program features an extra day of vacation once you hit 20 years.

That word you keep using...

I do not think it means what you think it means.

Larry Borsato says that Canadian cable companies are stealing content by inserting their own commercials into programs such as the Super Bowl, instead of showing the US commercials. That's the loosest definition of stealing I've heard in a while.

Perhaps Larry should give this a read.

I'm watching the Super Bowl so why don't I get to see the American ads?

In many cases, the ads for a given product aired in Canada and in the U.S. are the same. Reasons for those that aren't being aired in Canada, include: the American advertisers not purchasing commercial air-time from Canadian stations who have purchased the rights to air the Super Bowl; and the American products advertised are not available for purchase in Canada.

What is signal substitution?

Signal substitution most often involves substituting a Canadian signal for an American one. As a result, the viewer will see the program in its entirety but from a Canadian source.

During the Super Bowl, for example, Canadian broadcasters sell advertising time to be included in the Canadian feed of the program and replace the ads Americans see at home. This permits Canadian stations that buy the exclusive rights to air the Super Bowl in Canada, to benefit from the sale of commercial advertising during the airing of the program.


And if that's not good enough for you Larry, you can file a complaint.

How to file a broadcasting complaint.