C# TimeZoneInfo在两位代码中的工作方式不同
我的UI层中有一些代码,它应该采用UTC格式的日期时间,并将其转换为本地日期时间: 在我的数据层中,我只需执行以下操作:C# TimeZoneInfo在两位代码中的工作方式不同,c#,timezone,C#,Timezone,我的UI层中有一些代码,它应该采用UTC格式的日期时间,并将其转换为本地日期时间: 在我的数据层中,我只需执行以下操作: private DateTime ConvertToLocal(DateTime dt) { if (_currentTimeZoneUser == string.Empty) { var u = new UserData(_userId).GetUser(_userId); _currentTimeZoneUser = u.T
private DateTime ConvertToLocal(DateTime dt)
{
if (_currentTimeZoneUser == string.Empty)
{
var u = new UserData(_userId).GetUser(_userId);
_currentTimeZoneUser = u.TimeZoneId;
}
var reply = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(dt, _currentTimeZoneUser);
return reply;
}
这样做的目的是检查是否设置了_currentTimeZoneUser。如果没有,则从用户表中获取zimezone,然后进行转换
这段代码正在运行,我得到了一个有效的结果
然后我将代码复制到我的UI层(因为对于数据网格,我也需要在那里进行转换),但是“reply”总是等于“dt”
我在谷歌上搜索,发现我应该用一种稍微不同的方式来做。因此,我将UI方法更改为:
public static DateTime GetLocalDateTime(DateTime serverTime)
{
var timeZoneId = HttpContext.Current.Session["TimeZoneId"].ToString();
TimeZoneInfo cstZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneId);
var reply = TimeZoneInfo.ConvertTimeFromUtc(serverTime, cstZone);
return reply;
}
而且它有效
我不明白为什么它在我的数据层工作,但在UI中,我需要更改代码
我在其中一种方法中的时间转换代码是否有问题?如果我理解正确,您的问题可以归结为
ConvertTimeBySystemTimeZoneId
和ConvertTimeFromUtc
之间的差异
首先,您需要了解,任何涉及DateTime
的时区转换操作都可能会有行为差异,具体取决于DateTime
的.Kind
值。当您查看每种方法(和)的文档时,您会发现一个图表,其中描述了三种不同类型(Utc
、Local
和未指定的
)的行为
这是.Net中的一个痛处,这就是为什么存在类似的库。您可以在这两篇文章中阅读更多内容:
DateTime
谁是。Kind
是未指定的。在ConvertTimeBySystemTimeZoneId
方法中,它将被视为Local
,而在ConvertTimeFromUtc
方法中,它将被视为Utc
有两种解决办法
- 第一个是您已经找到的-使用
ConvertTimeFromUtc
方法。您也应该在服务器代码中这样做
- 第二种解决方案是在从数据库加载值时,将
.Kind
设置为Utc
。在某些地方,您可能有这样的代码:
foo.MyDateTime = (DateTime) dataReader["MyDateTime"]
这将改变为:
foo.MyDateTime = DateTime.SpecifyKind(
(DateTime) dataReader["MyDateTime"],
DateTimeKind.Utc);
我假设您正在使用DataReader
响应进行直接ADO.Net调用。根据您实际正在做的事情进行相应调整。这完全是错误的想法。当您使用HttpContext时,对本地时间感兴趣的唯一实体就是用户,数千英里,以及从web服务器上删除的不可用的时区数。在服务器端严格使用UTC,在浏览器中转换为本地时间。@HansPassant-这需要JavaScript,但这并不总是可能的,而且在这方面存在缺陷。在服务器端代码中进行时区转换没有错,只要您知道用户的时区id,他就是这样做的。