When I write trial apps in Ruby, I do this.
I pick my date in the future that I want the trial to expire. I convert this to float. Then at runtime, I get the current date, convert to float, and compare.
A twist to this that I have done is to change the plist to set a flag that the trial period has been exceeded. This causes a persistent indicator to be set. That way, just a simple "set the clock back" won't get around my intent of expiring the trial period - the user would have to go to greater lengths to circumvent the trial period.
Obviously, there are relatively simple ways to circumvent this, like setting the clock back prior to the period expiring. I added logic to check for this, like each time the program starts, set the current time in the plist, and if the current time was ever a time prior to the saved time, end the trial then and there.
I think the next wave of trial-ending checks I develop will be across the net. I'll have the code "phone home" and use the clock on our server. This would require the user to have a network connection active, which, is not really inconvenient I guess, but could be limiting for a user.
Actually, along this same line, I'm considering not even distributing the core part of the code, but just distributing a stub program that phones home to get itself at runtime (using AJAX). This would work not only for a trial period, but also to cut down on pirated code. Also, the user always gets the latest version of the code, and there's nothing for them to pirate, as their credentials get validated each time at runtime, and the code is never stored on their hard drive in a manner which is easy to duplicate.
Todd