There are a few unknowns in your question as you have stated it.
When I have done this sort of work, the solution has always been the second approach you offered. This is because if you need aggregate data across a significant set of users it is way easier to do this on 30 minute aggregates than it is to try to recalculate a bunch of timezones.
This being said, if you have a particular case where you need per timezone aggregates across users, that may be different. To be honest, though, I am having trouble thinking of such cases.
So I would certainly stick with 30 minute UTC-based approaches first, and only consider tweaking if that proves insufficient for some reason.