开发者

.NET: Accounting for daylight savings

I have a method that creates a UTC DateTime from user input, using the GMT offset of their geographical position:

public static DateTime LocalToUtc
    (int year, int month, int day, int hour, decimal gmtOffset) {

    // argument validation here

    var dateTime = new DateTime(year, month, day).AddHours(hour);
    var dateTimeOffset = 
        new DateTimeOffset(dateTime, TimeSpan.FromHours(gmtOffset));

    return dateTimeOffset.UtcDateTime;

} 

The problem is that this function is 开发者_运维技巧off by an hour if it's daylight savings in the user's timezone.

So while my personal GMT offset is -8, the current timezone offset is -7 because of daylight savings.

How do I change the function above to account for daylight savings? Don't I somehow need to create some timezone object from the GMT offset and get its timezone offset?


There is no way to do it without knowing the actual time zone: several time zones have the same base UTC offset, but with different rules for daylight saving time. For instance, W. Europe Standard Time and W. Central Africa Standard Time both have an offset of +01:00, but the former supports DST while the latter doesn't. So the offset is not enough to decide whether DST applies or not...

Your method should take a TimeZoneInfo parameter instead of gmtOffset. This way you can just use the TimeZoneInfo.ConvertTime method to convert the date, it will automatically take DST into account.


DateTime already has methods to do this called ToLocalTime() and ToUniversalTime(). What's wrong with using that?

EDIT:

Based upon the comment that the author is looking to convert to utc from a timezone other than the current computers timezone, then I refer you to John Skeets answer Here

From the MSDN documentation:

string displayName = "(GMT+06:00) Antarctica/Mawson Time";
string standardName = "Mawson Time"; 
TimeSpan offset = new TimeSpan(06, 00, 00);
TimeZoneInfo mawson = TimeZoneInfo.CreateCustomTimeZone(standardName, 
    offset, displayName, standardName);
Console.WriteLine("The current time is {0} {1}", 
                  TimeZoneInfo.ConvertTime(DateTime.Now, 
                       TimeZoneInfo.Local, mawson), mawson.StandardName);      


You should use the TimeZone.GetUtcOffset Method if you don't want to use the built-in UTC method.

http://msdn.microsoft.com/en-us/library/system.timezone.getutcoffset.aspx

It will give you your offset to UTC. You could also use the built-in methods to get UTC time from local times.

http://msdn.microsoft.com/en-us/library/system.datetime.touniversaltime(v=VS.100).aspx


Since it sounds you're asking users for a time offset that might not necessarily be in the machine's local time zone, the local machine time wouldn't work. But using the TimeZoneInfo class, you should be able to construct an instance that accounts for the offset and DST status and use the built-in methods from there.

Edit: On my machine, at least, TimeZoneInfo.GetSystemTimeZones() seems to return all valid time zones. This could be easily mapped to a drop-down menu to allow the user to select.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜