I understand this is an answered question. I am adding my few cents also for future reference. This is also another approach.
My Complete Solution as follows. All the time is stored as UTC in database. You can choose another timezone as default. But then calculation get complicated. And if you decided to move your host to another country, it would be issue.
Database
First, Need to store user selected timezone in some table that holds user information. Basically we are going to store TimeZoneInfo.Id (String value). This is easy to create TimeZoneInfo class again.
Next, Create a User defined function and set return as datetime. This will be used in whole DB where ever you need server time. Code as shown,
Create FUNCTION [dbo].[fnGetDateTime] ()
RETURNS datetime
AS
BEGIN
RETURN GETUTCDATE()
END
This will return UTC time. We can use GETUTCDATE() method straightaway everywhere in the db. But using a UDF gives flexibility on maintenance.
Code
we can use method extendability in Date-time Class. Since this solution is based on asp.net, it is tricky to calculate time. Problem is, there are 3 parties involved. DB Server, Web Server and User. Each can be in different time zone. But we need to solely relay on User Selected time zone and UTC time.
I have exetened DateTime Strucute with 2 addtional methods.
Namespace Extensions
Public Module ModDateTimeExtensions
<System.Runtime.CompilerServices.Extension()> _
Public Function GetUserTimeFromUTC(ByVal dtUtcTime As DateTime, ByVal id As String) As DateTime
Return TimeZoneInfo.ConvertTimeFromUtc(dtUtcTime, TimeZoneInfo.FindSystemTimeZoneById(id))
End Function
<System.Runtime.CompilerServices.Extension()> _
Public Function SetUserTimeToUTC(ByVal dtUserTime As DateTime, ByVal id As String) As DateTime
Return TimeZoneInfo.ConvertTime(dtUserTime, TimeZoneInfo.FindSystemTimeZoneById(id), TimeZoneInfo.Utc)
End Function
End Module
End Namespace
Here important thing you shouldn't relay on web-server time zone for calculation.
Then basically you can do the conversion as below. Assuming user time zone set to "Pacific Standard Time". This needs to be pulled from DB during user login.
Dim dt as DateTime = FunctionToGetUTCTimeFromDB()
dt = dt.GetUserTimeFromUTC("Pacific Standard Time")
If you want to save user time to UTC then call,
Dim dt as DateTime = GetUserSelectedTimeFromUI()
dt = dt.SetUserTimeToUTC("Pacific Standard Time")
This gives Following flexibility,
Less Coding and Less Change if it needs to be implemented in existing system.
Easy maintenance.
In future if you want to implement User selectable date time format, can follow same way with small change.