cho*_*bo2 56 .net c# asp.net asp.net-mvc
我将所有日期都以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"
Run Code Online (Sandbox Code Playgroud)
我不知道为什么我会这样做.
我试过两种方法
TimeZoneInfo zone = TimeZoneInfo.FindSystemTimeZoneById(id);
// I also tried DateTime.UtcNow
DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
var utc = TimeZoneInfo.ConvertTimeToUtc(now , zone );
Run Code Online (Sandbox Code Playgroud)
这失败了所以我累了
DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
var utc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(now,
ZoneId, TimeZoneInfo.Utc.Id);
Run Code Online (Sandbox Code Playgroud)
这也失败了同样的错误.我究竟做错了什么?
编辑会这样吗?
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);
Run Code Online (Sandbox Code Playgroud)
编辑2 @ Jon Skeet
我只是在考虑我甚至不需要做这一切.时间的东西现在让我困惑,所以这就是为什么这篇文章可能不那么清晰.我永远都不知道DateTime.Now到底是什么(我试图将我的时区更改为另一个时区,并且它一直保持当地时间).
这就是我想要的东西.用户来到网站添加一些警报,它现在保存为utc(在它之前是DateTime.Now然后有人建议存储所有UTC).
因此,在用户访问我的网站之前,根据我的托管服务器的位置,它可能就像第二天一样.因此,如果警报据说是在8月30日(他们的时间)显示,但是服务器的时差可以在8月29日到来,并且会显示警报.
所以我想打击那个.所以现在我不确定我是否应该存储他们的当地时间然后使用这个偏移的东西?或者只存储UTC时间.仅仅存储UTC时间仍然可能是错误的,因为用户仍然可能会在当地时间考虑并且我不确定UTC是如何工作的,它仍然可能最终会产生时间差异.
EDIT3
var info = TimeZoneInfo.FindSystemTimeZoneById(id)
DateTimeOffset usersTime = TimeZoneInfo.ConvertTime(DataBaseUTCDate,
TimeZoneInfo.Utc, info);
Run Code Online (Sandbox Code Playgroud)
SLa*_*aks 94
您需要设置Kind为Unspecified,如下所示:
DateTime now = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Unspecified);
var utc = TimeZoneInfo.ConvertTimeToUtc(now , zone);
Run Code Online (Sandbox Code Playgroud)
DateTimeKind.Local表示在本地时区,而不是任何其他时区.这就是你得到错误的原因.
dtb*_*dtb 38
该DateTime结构仅支持两个时区:
看看DateTimeOffset结构.
var info = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");
DateTimeOffset localServerTime = DateTimeOffset.Now;
DateTimeOffset usersTime = TimeZoneInfo.ConvertTime(localServerTime, info);
DateTimeOffset utc = localServerTime.ToUniversalTime();
Console.WriteLine("Local Time: {0}", localServerTime);
Console.WriteLine("User's Time: {0}", usersTime);
Console.WriteLine("UTC: {0}", utc);
Run Code Online (Sandbox Code Playgroud)
输出:
Local Time: 30.08.2009 20:48:17 +02:00
User's Time: 31.08.2009 03:48:17 +09:00
UTC: 30.08.2009 18:48:17 +00:00
Run Code Online (Sandbox Code Playgroud)
正如dtb所说,DateTimeOffset如果你想存储具有特定时区的日期/时间,你应该使用它.
但是,从你的帖子中可以清楚地知道你真的需要这样做.您只使用示例,DateTime.Now并且您说您猜测您正在使用服务器时间.你几点想要什么时间?如果您只想要UTC中的当前时间,请使用DateTime.UtcNow或DateTimeOffset.UtcNow.你不需要知道时区就知道当前的UTC时间,正是因为它是通用的.
如果您以其他方式从用户那里获得日期/时间,请提供更多信息 - 这样我们就能够确定您需要做的事情.否则我们只是在猜测.
其他人的答案似乎过于复杂.我有一个特定的要求,这对我来说很好:
void Main()
{
var startDate = DateTime.Today;
var StartDateUtc = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(DateTime.SpecifyKind(startDate.Date, DateTimeKind.Unspecified), "Eastern Standard Time", "UTC");
startDate.Dump();
StartDateUtc.Dump();
}
Run Code Online (Sandbox Code Playgroud)
哪个输出(来自linqpad)我的预期:
12/20/2013 12:00:00 AM
12/20/2013 5:00:00 AM
对于未指明类型的提示,道具为Slaks.这就是我所缺少的.但所有关于只有两种日期(本地和UTC)的讨论都让我感到困惑.
仅供参考 - 我运行的机器是在中部时区,而DST没有生效.
| 归档时间: |
|
| 查看次数: |
57044 次 |
| 最近记录: |