D-Programming-Language/phobos — pull request #2088 by jmdavis (2014-04-20 10:45:08+00:00)
Title: Fix issue# 12507: SysTime.init.toString() blows up.

It didn't used to be possible for member variables which were classes to be initialized at compile time, so `SysTime`'s `timezone` member defaults to null, which means that `SysTime.init` segfaults for a lot of its functions. It is now possible for member variables which are classes to be initialized at compile time.

What this pull does is create a new, private `TimeZone` - `InitTimeZone` - for `SysTime.init`'s use. It allows `SysTime.init` to be unique when comparing with the `is` operator, and it allows `SysTime.init`'s functions to do something special for `SysTime.init` where appropriate. In particular, `toString` now returns `"SysTime.init"` for `SysTime.init`, and all functions - save for assignment - which would otherwise mutate a default-initialized `SysTime` will not mutate it. This should make debugging with `SysTime.init` easier, and it avoids any weird behavior that we'd get by trying to make `SysTime.init` special with regards to `toString` but allowing it to be mutated to other values with the same `timezone` (in which case, we could have gotten `toString` printing `SysTime.init` when the `is` operator would have returned `false` for `st is SysTime.init`, because the `timezone`s would have matched, but not the `stdTime`s).

This does have the downside of adding some minor overhead to functions which mutate `SysTime` without calling `adjTime` (`InitTimeZone` takes care of `adjTime` by always returning `0` for all conversions), but it should just be a pointer comparison (at least, if `-inline` is used), and without that, I really don't feel comfortable having `toString` return anything special for `SysTime.init`, since we'd risk the aforementioned weird behaviors if we did.

`SysTime.init` is equivalent to `"0001-01-01T00:00:00+00:00"` and will return that for `toISOExtString`.

You'll probably want to look at this in separate commits, since the second commit involves a lot of indentation changes (it's also easier to look at if whitespace changes are ignored). I removed all of the `version(testStdDateTime)` blocks from the unit tests in `SysTime`, since they aren't necessary anymore.