I'd have to recommend storing all your times in UTC, then also storing the user's timezone offset. This allows for maximum flexibility, and some decent separation between actual data (UTC time) and display logic (UTC +/- Offset).
For storage, no matter how many times I try RDBMS specific time fields, unix timestamps in an int field always offer the best flexibility and portability.
You could store the user's timezone offset in seconds to make the process even simpler. So EST (-5) would become -18 000
Then, for displaying time -/+ user's offset, simple second maths will work just fine:
$now = time();
$userTime = $now + $user->getTimezoneOffset();
This'll work fine because adding a negative number is just like subtracting a positive one.
Edit:
You will be able to format the user's timestamp using PHP's standard gmdate() function. Just pass the calculated timestamp as the function's second parameter. See http://ca2.php.net/manual/en/function.gmdate.php
Whoops... date() is current locale aware. should use gmdate() instead.
There is of course, one totally different approach which may be better:
Store a textual representation of the User's timezone which is compatible with PHP's date_default_timezone_set() . Then, on each request, if you have an authenticated user, you can set timezone, and all date functions will obey it.