.NET:考虑夏令时

时间:2011-04-27 22:14:04

标签: c# .net datetime localization

我有一个方法,使用其地理位置的GMT偏移量从用户输入创建UTC DateTime

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;

} 

问题是,如果在用户的时区节省了夏令时,此功能会暂停一小时。

因此,当我的个人GMT偏移为-8时,由于夏令时,当前时区偏移为-7。

如何更改上述功能以解决夏令时问题?我不是需要从GMT偏移量创建一些时区对象并获得其时区偏移量吗?

4 个答案:

答案 0 :(得分:2)

如果不知道实际时区,则无法执行此操作:多个时区具有相同的基本UTC偏移,但具有不同的夏令时规则。例如, W.欧洲标准时间 W.中非标准时间的偏移量均为+01:00,但前者支持DST,后者则不支持。所以偏差不足以决定是否适用DST ......

您的方法应采用TimeZoneInfo参数而不是gmtOffset。这样您就可以使用TimeZoneInfo.ConvertTime方法转换日期,它会自动将DST考虑在内。

答案 1 :(得分:1)

DateTime已经有了执行此操作的方法ToLocalTime()ToUniversalTime()。使用它有什么问题?

编辑:

基于作者希望从当前计算机时区以外的时区转换为utc的评论,我建议您转到John Skeets的回答Here

来自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);      

答案 2 :(得分:0)

如果您不想使用内置的UTC方法,则应使用TimeZone.GetUtcOffset方法。

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

它将为您提供UTC的偏移量。您还可以使用内置方法从当地时间获取UTC时间。

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

答案 3 :(得分:0)

由于听起来您要求用户的时间偏移量可能不一定在机器的本地时区,因此本地机器时间不起作用。但是使用TimeZoneInfo类,您应该能够构造一个考虑偏移和DST状态的实例,并使用那里的内置方法。

编辑:至少在我的计算机上,TimeZoneInfo.GetSystemTimeZones()似乎会返回所有有效时区。这可以很容易地映射到下拉菜单,以允许用户选择。