I have MVC web application. I am storing UTC time in database. (Not datetime but just a time). In C# When I retrieve this time from the database I get timespan object back. I also have offset available in minutes. For example.
double offset = 600;
How do I use this offset to convert timespan to local datetime.
Note I don't want to use DateTime.ToLocalTime () method because that will use server's timezone.
UPDATE1
I am using the Javascript new Date().getTimezoneOffset()
method to get the client's offset, and i have offset value stored on the server. Then I also have drop down list that show times as 12:00 AM, 12.30 AM, 1:00 AM etc etc. The dropdownlist is bound to model property SelectedDateTime
of type DateTime
. Idea is to convert user selected time to UTC and then UTC to localtime based on the offset. So lets say i have offset 300 minitues
that would be 300/60 = 5 hours
double offset = 5.00; // this is available on the server
When the user selects time in a drop down list, I am getting a datetime object on the server, ignoring the date part i want to store UTC time into database. This is how I'm converting to UTC time.
TimeSpan utcTime = SelectedDateTime.AddHours(offset).TimeOfday;
I store this utcTime into the database. Now I want to convert UTC timespan into the client's datetime. I am assuming i have Subtract offset now
var newLocalTimeSpan = utcTime.Subtract(TimeSpan.FromHours(offset));
var newLocalDateTime = new DateTime(newLocalTimeSpan.Ticks, DateTimeKind.Local);
However this throws the error:
Ticks must be between DateTime.MinValue.Ticks and DateTime.MaxValue.Ticks.\r\nParameter name: ticks
For example with offest 5
hours, If user selects 8:00 PM
then it will be converted to UTC and will be stored as 01:00:00.0000000
in database. When I retrieve the UTC value from database its '1:00:00 AM'. Then I subtract 5 hours form this TimeSpan which equals to `-4' now and if I pass Ticks to DateTime..i get above error.
NOTES: If you are curious why model property is DateTime instead of TimeSpan thats because i am using Kendo TimePicker which needs DateTime type.
UPDATE 2
I really appreciate all for your help. I have gone through all the articles @Matt Johnson has posted and it looks like I should not be using offset for calculating the UTC time. Mainly because of the day light time saving. But instead I should be using timezone. So I have 3 options here to find client’s time zone:
1> Use JavaScript to detect time zone
In JavaScript I can do new Date().toString()
which returns date time as Sun May 22 2016 02:12:36 GMT-0500 (Central Daylight Time)
I can then parse the string to get “Central Daylight Time” and post it to the server. However on server, for .net “Central Daylight Time” is not a valid windows time zone ID.
Question
Is this correct approach? Is JavaScript returning IANA zone id? Will it always return IANA zone id?
If JavaScript is returning IANA
Id then I can use Matt’s article here to get windows time zone id
2> Use http://momentjs.com/ to detect client’s time zone
Question
Is momentjs returns IANA
zone id?
If momentjs return IANA
zone id then I can use Matt’s article above to get windows zone id. One of the reason I don’t like this approach is because I have to use 2 third party libraries momentjs
and Noda Time
3> Provide user a drop down list using TimeZoneInfo.GetSystemTimeZones() and let the user selects the timezone.
User will select a time and timezone, then on server I will convert it to UTC using selected timezone and save it DB. However I have to show that time on some other pages, So I again need timezone. That means I have to put the drop down list in such a place on UI where it will be available all the time. Like top menu.
(I can certainly save timezone into DB along with the time, however if user travel to other place he will still see time in initially selected time zone. Which I don’t want)
Are these correct approaches? Am i missing something?
Question
Assume that I implement timezone selection using one of the approach above and i have correct client's time zone with windows timezone id on server in some variable.
Now lets say user selects 6:00 PM
(Central Daylight Time , UTC -5) which will convert to UTC as 23:00:00. As long we are in Central Daylight Time the conversion from UTC to local will show 6:00 PM. Once we go into Central Standard Time
which is UTC -6 Will the conversion still show 6:00 PM or 5:00 PM?
I am planning to use TimeZoneInfo.ConvertFromUtc(datetimevalue, timezone)
method for converting UTC to Local