C# .NET:夏令时会计
我有一种方法,可以使用用户输入的地理位置的GMT偏移量创建UTCC# .NET:夏令时会计,c#,.net,datetime,localization,C#,.net,Datetime,Localization,我有一种方法,可以使用用户输入的地理位置的GMT偏移量创建UTCDateTime: 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
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偏移量创建一些时区对象并获取其时区偏移量吗?DateTime已经有了这样做的方法,称为
ToLocalTime()
和ToUniversalTime()
。用这个有什么不对
编辑:
根据作者希望从当前计算机时区以外的时区转换为utc的评论,我建议您参考John Skeets的答案
从:
如果不想使用内置UTC方法,则应使用
TimeZone.GetUtcOffset
方法
它将为您提供UTC的偏移量。您还可以使用内置方法从本地时间获取UTC时间
因为听起来您是在向用户询问可能不一定在机器本地时区的时间偏移,所以本地机器时间不起作用。但是使用该类,您应该能够构造一个说明偏移量和DST状态的实例,并从中使用内置方法
编辑:至少在我的机器上,
TimeZoneInfo.GetSystemTimeZones()
似乎会返回所有有效的时区。这可以很容易地映射到一个下拉菜单,以允许用户进行选择。如果不知道实际时区,则无法进行选择:几个时区具有相同的UTC基准偏移,但夏令时规则不同。例如,W.Europe标准时间和W.Central Africa标准时间都有+01:00的偏移量,但前者支持DST,而后者不支持。所以偏移量不足以决定DST是否适用
您的方法应该采用
TimeZoneInfo
参数,而不是gmtOffset
。这样,您只需使用TimeZoneInfo.ConvertTime
方法来转换日期,它会自动将DST考虑在内。DateTime在不同时区中差异值时存在错误。当UTC、Local的类型根本没有设置时,这尤其令人恼火。@GregC-不,这不是bug。您只是不能始终确保DateTime具有正确的localtime信息集。这就是为什么要转换为UTC进行比较。@Mystere Man,GregC是对的,DateTime结构不适合处理不同的时区。这正是DateTimeOffset结构被引入的原因…@Mystere-Man:尝试使用DateTime.Now创建一个新的DateTime对象,使用DateTime.UtcNow创建另一个对象。改变一下。观察错误(除非您使用GB)。当日期时间中不包含GMT偏移信息时,如何使用新的日期时间(年、月、日)。AddHours(小时)。ToUniversalTime()?它如何知道使用什么GMT?如何获取时区对象来调用GetUtcOffset?我只知道用户的GMT偏移量。GMT偏移量是根据地理数据集计算的。他们必须在注册时选择lat/lng。然后在DB表中查找lat/lng,该表导出GMT偏移量。他们输入lat/lng是专门为了获取时区,还是也用于其他目的?如果没有,您可以使用TimeZoneInfo.GetSystemTimeZones()
并为用户提供下拉选择。或者:该数据集是否只提供偏移量或DST信息?如果它有DST信息,你可以动态创建一个TimeZoneInfo的自定义实例。好吧,假设我有数据告诉我它们在哪个时区。如何创建TimeZoneInfo对象?换句话说,我们将参数更改为TimeZoneInfo。可以然后我们需要一个TimeZoneInfo对象来发送给函数。这是如何构造的?您可以使用TimeZoneInfo.FindSystemTimeZoneById
方法。或者,您可以使用TimeZoneInfo.GetSystemTimeZones
方法获取所有时区的列表,并让用户从该列表中进行选择。或者您可以调用TimeZoneInfo.CreateCustomTimeZone来实例化您想要的任何时区。
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);