<p><em>This is javascript, but a virtually identical regex is failing in PHP too, so I don't think it's language specific</em></p>

<pre><code>var r = new RegExp(
    "^(:19|20)?[0-9][0-9]"            // optional 19/20 start followed by 2 numbers
    + "-"                             // a hyphen
    + "(:0?[1-9]|1[0-2])"             // optional 0 followed by 1-9, or 10, 11, 12
    + "-"                             // a hyphen
    + "(:3[01]|[12][0-9]|0?[1-9])$"   // you get the idea.
);
r.test("2008-07-01");                // == false
</code></pre>

<p>What on earth am I missing?</p>

I think your non-capturing blocks should be e.g.
```
(?:19|20)
```
rather than
```
(:19|20)
```