我在数据库中以UTC格式存储所有日期。我向用户询问他们的时区,希望使用他们的时区和我猜测的服务器时间来为他们找出UTC。
一旦我得到了UTC,我想进行搜索,以查看数据库中使用他们新转换的UTC日期的范围。
但我总是遇到这个异常。
System.ArgumentException was unhandled by user code
Message="The conversion could not be completed because the
supplied DateTime did not have the Kind property set correctly.
For example, when the Kind property is DateTimeKind.Local,
the source time zone must be TimeZoneInfo.Local.
Parameter name: sourceTimeZone"
我不知道为什么会出现这种情况。
我尝试了两种方法。
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(id);
// I also tried DateTime.UtcNow
DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
var utc = TimeZoneInfo.ConvertTimeToUtc(now , zone );
这失败了,所以我尝试了
DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
var utc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now,
ZoneId, TimeZoneInfo.Utc.Id);
这个方法也出现了同样的错误。我做错了什么?
编辑:这样行吗?
DateTime localServerTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
TimeZoneInfo info = TimeZoneInfo.FindSystemTimeZoneById(id);
var usersTime = TimeZoneInfo.ConvertTime(localServerTime, info);
var utc = TimeZoneInfo.ConvertTimeToUtc(usersTime, userInfo);
编辑2 @ Jon Skeet
是的,我刚才想到可能根本不需要做所有这些。时间的问题让我感到困惑,所以帖子可能没有应该有的那么清晰。我从不知道DateTime.Now在获取什么(我尝试将时区更改为另一个时区,但它仍然获取我的当地时间)。
这就是我想要实现的:用户来到网站,添加一些警报并将其保存为utc(之前是DateTime.Now,然后有人建议将所有内容都存储为UTC)。
因此,以前用户会来到我的网站,取决于我的托管服务器的位置,可能会像下一天一样。因此,如果警报被设置为8月30日(他们的时间)显示,但由于服务器的时差,他们可能会在8月29日进入,警报将会显示。
所以我想要处理这个问题。现在我不确定是否应该只存储他们的本地时间,然后使用这个offset?还是只存储UTC时间。仅存储UTC时间仍然可能是错误的,因为用户仍然可能会按本地时间思考,而我不确定UTC如何真正工作。这仍然可能导致时间差异。
编辑3
var info = TimeZoneInfo.FindSystemTimeZoneById(id)
DateTimeOffset usersTime = TimeZoneInfo.ConvertTime(DataBaseUTCDate,
TimeZoneInfo.Utc, info);
DateTime.Now.Kind
已经是Local
,你不需要调用SpecifyKind
。 - SLaks