Here's my opinion.
The weak point of any time-limit or dongle-protection is that in the end everything must be checked with an 'if' statement. In the old 'x86 days there is JNE, JE, JNZ family of instructions. Such 'if' statement must exist in hundreds if not thousands or more in the application. So any cracker must find out where to start looking, for instance, dongle checkers almost always use DeviceIoControl API, which could be pinpointed quickly. After the calls to DeviceIoControl API found, the cracker just reverse engineered the routine around the API call, and try change JNE instructions around that to JE or the other way around.
In your case, the usage of DateTime is the tell-tale (but of course, there is a lot of place where DateTime being used for other things, that makes it harder for the cracker). To make things difficult for the cracker, copy the current date to some object's values, and try to make, like, 20 places or something that stores the DateTime. Or even better, retrieve current date from the net and also from the current computer. Don't check the DateTime directly, but use the value that you store in some objects before, to make it harder for the cracker. Use consistency check mechanism to ensure the dates are within tolerance, and kill the app if you find out that 2 of the datetime is different to the other stored datetime (give 2 days tolerance or so).
Also check whether the clock is not turned back by the user, if you found out that CurrentDateTime < StoredDateTimeInRegistry then you should store a kill flag somewhere in the registry. Or you might also want to use a file in addition to the registry.
For every kind checks you do, try to do it in many places and in different ways.
At the end, I must say that what Bigbohne said is true (nothing is impossible to crack) - it is just that, by making it difficult for the cracker, we changed his/her effort-to-result ratio, and hopefully discouraging him from continuing the cracking process.