2015-11-02

What does a 200-year-old professor from Ireland and a 900-year-old Jedi Master have in common?

See page for author [Public Domain],
via Wikimedia Commons
This is not another joke. But the question in the title ponders what George Boole has in common with Yoda. The answer, of course, is one of Yoda's classic aphorisms: "Do. Or do not. There is no try." which parallels the mathematical logic system created by George Boole - what we now know as Boolean Logic.

George Boole was the first to express the mathematics behind the logical operations we use today: XOR (which he saw as binary addition modulo 2) and AND (which was binary multiplication). The OR and NOT operations were added later. And although he was something of a contemporary to Charles Babbage, the two never met to discuss their similar ideas, although Boole was very interested in automation. His mathematical logic also foretold some AI operations, as he sought to use his theory to help explain how people thought and reasoned.

The XOR operation takes two binary numbers, adds them together, and then just looks at the rightmost digit for the result. It is an "exclusive OR" - the result will be 1 if, and only if, only one of the values being added is 1. We can make a simple table:
0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0

Even simpler, the AND operation also takes two binary numbers and multiplies them. The result will be 1 if, and only if, both of the values are 1. Another simple table:
0 x 0 = 0
1 x 0 = 0
0 x 1 = 0
1 x 1 = 1

Boolean logic in coding

Decades after Boole's work, Shannon realized that his math could be applied to digital circuits, and thus to the computing that was evolving in the 1930s. We're most familiar with these operators today in slightly different forms. Instead of the XOR of Boole's time, we have a disjunctive OR which is more similar to how we use the word "or" in English.
0 v 0 = 0
0 v 1 = 1
1 v 0 = 1
1 v 1 = 1
The alert among you might figure out that a OR b == (a XOR b) XOR (a AND b).

Combined with NOT, which turns a 0 into a 1 and a 1 into a 0, we have the fundamental operations that most of us might use in an "if" statement, or many other conditional operations today in most programming languages.

Many languages are willing to play fast and loose with the concept of what represents false and true. Most agree that a zero will be false - but that anything non-zero ends up being true. Some languages are more strict - they have a boolean type and only things that evaluate to boolean types can be used with AND, OR, and NOT operations. Languages that aren't as strict are easier to work with - but also easier to make mistakes with. (Many is the time that a programmer meant to compare two values, ended up assigning one to the other, and getting a comparison result that was wrong.)

Combining boolean logic with multiple bits allow computers to do masking and quick comparisons and are a the heart of most graphics drivers and programming language implementations.

Most, but not all

All of this seems pretty straightforward, but it was pretty revolutionary when Boole came up with it in the 19th century. And it isn't guaranteed to be valid even in all programming languages today. For example, SQL appears to implement boolean logic, but actually has a third possible value which throws all the logic conditions out the window. Since SQL values can be null, which cannot be compared to non-null values, you can get operations which, when tested, and when their negation is tested, both evaluate to false. But that is a complication for another time.

2015-11-01

Don't count your seconds before they're hatched

or Why coders hate Daylight Saving Time.

Today marks the end of Daylight Saving Time in the US - what other countries sometimes call
Summer Time. A legislative attempt to reconcile how people use a clock with how the sun behaves seasonally. I'm not really going to debate or discuss the merits vs pitfalls of DST since they're not relevant at the moment, but I'll explore how, as programmers, we can't always assume that certain physical constants are actually constant.

Like the number of seconds between noon on two consecutive days.

The Problem

Most of the time - this isn't really a problem. One day has 24 hours, each hour has 60 minutes, each minute has 60 seconds. That comes to 86400 seconds in a day. What could be simpler?

Except on days like today when DST ends. That means that at 2am Daylight Saving Time it became 1am Standard Time. So between the midnight when the day began and the midnight when it ends, there was an extra hour which corresponds to an extra 3600 seconds. So there are 90000 seconds today. The opposite is true when DST begins - at 2am Standard Time it becomes 3am Daylight Saving Time, so there are only 82800 seconds in the day.

It gets even more confusing when you consider that the rules for DST aren't consistent. The weekend they change has changed over time, and there were even some times when it was in effect year-round. Some locations didn't have DST and have adopted it, while others don't need it for their location.

And don't think this is just about days and odd times of the year. We've gotten used to it, but keep in mind that there are a variable number of days in the year when you consider leap years. And there is a hot debate about the use of the leap second to keep atomic clocks in sync with astronomical clocks.

But so what? Aren't coders wise enough to all this to avoid any problems? Well...

The Impact

There have been a surprising number of cases where this wasn't true. Time and again, operating systems have been wrong on the day after DST begins or ends because they computed it wrong. Many schedulers have done things like failed to run jobs because an hour was skipped over during the change to DST, or run twice during the change away from it.

It gets even more confusing when you throw in time zones and consider that different time zones may apply the DST rules at different times of the year (such as just happened now - Europe and the US left summer time at different times).

For example, what if you're writing a calendar program. One common task is to schedule something for "2:00 every afternoon". A simplistic solution might have you do this:
  • You'll store this task as the time the event first happens in number of seconds since some date (an epoch time).
  • You'll then compute every other time this will happen by adding a multiple of 86400 seconds to that.
So what would that have scheduled?
  • October 30th, 2pm Daylight Saving Time
  • October 31st, 2pm Daylight Saving Time
  • November 1st, 1pm Standard Time
  • November 2nd, 1pm Standard Time
That doesn't look right!

It shows up in other places as well. What if you're writing a program that lets you view how much energy you've used every hour for the day before? Most days will be no problem - 24 hours in the day, 24 lines. But one day a year will have 25 hours, and one day will have 23. How will you show this so it isn't confusing? If someone asks for the 1am reading, what will you return?

The Solution

Well... there isn't one.

There are several tricks we can try, of course, but there is no "one size fits all" solution to this issue. It really depends on the exact case.

For our calendar example above, we need to do the calculations and take Daylight Saving into account. If we're storing it in a database, we'll need to store what we want ("every day at 2pm") rather than the results of the calculation so we can re-calculate if DST rules change.

When it comes to displaying days with more than 24 hours, we just have to be aware that they will happen and leave room for them. For queries for 1am (rare, but they will happen, you can count on that), we need to be able to handle situations where more than one result will be returned or find a way to specify which version of 1am we want - the Standard Time version or the Saving Time version.

Above all, however, we have to keep in mind that this isn't a straightforward issue... and that the time that we're reporting has to be used by people, who are using time in their own ways and for their own purposes.

Don't waste time - keep quirks like these in mind as you program.