C# 使用WCF服务和DataTable序列化/反序列化时停止DateTime的自动本地化
我搞不懂这件事,快把我逼疯了。我无法理解为什么数据类型对象会这样做。我觉得指定的处理时区的类型就足够了。不管怎样,这是我的设置。我有一个WCF服务,它向我的应用程序提供一个序列化数据表。数据通过web界面输入。如果我将2014年12月12日上午11:00输入数据库,它将通过web服务严格地将数据表中的2014年12月12日下午12:00返回到我的应用程序 我怎么才能阻止这一切 事件链:C# 使用WCF服务和DataTable序列化/反序列化时停止DateTime的自动本地化,c#,wcf,datetime,serialization,C#,Wcf,Datetime,Serialization,我搞不懂这件事,快把我逼疯了。我无法理解为什么数据类型对象会这样做。我觉得指定的处理时区的类型就足够了。不管怎样,这是我的设置。我有一个WCF服务,它向我的应用程序提供一个序列化数据表。数据通过web界面输入。如果我将2014年12月12日上午11:00输入数据库,它将通过web服务严格地将数据表中的2014年12月12日下午12:00返回到我的应用程序 我怎么才能阻止这一切 事件链: 登录到web界面,选择立即执行任务(传递DateTime.now)或稍后执行任务(解析用户选择的日期时间常数的
对于这样一个老问题,我厌倦了在成堆的工作环境中挖掘,这些工作都没有,或者有足够好的决议来解释该做什么以及如何处理这个问题。我得到了它,尽管它做了很多调整。这也是我的特定设置,可能不适用于所有人 我的设置: 日期时间从数据库所在时区的web界面传递到数据库。在相同时区中运行的Windows服务根据show after字段循环并拉出任务。然后从任何时区的手机应用程序中提取该数据,并以多长时间前(如1分钟前、2小时前等)的形式显示值。手机应用程序是唯一与WCF服务接口的应用程序。由于Windows服务驻留在同一台服务器上,因此不需要任何中间人 首先,在网站上输入这些“任务”时,日期和时间通过以下方式获得
Double selectedTimezone = 0D;
Double offsetTimezone = 0D;
TimeZoneInfo timezoneInfo = TimeZoneInfo.Local;
selectedTimezone = Double.Parse(DDL_EndTimezone.SelectedValue.ToString());
/* Obtain the timezone offset for server to user.
For me this is -1: -6 (CST) to -5 (EST) */
offsetTimezone = (timezoneInfo.BaseUtcOffset.TotalHours - selectedTimezone);
/* Parse the date time from the selected user
inputs. */
if (!chkSendMessageNow.Checked)
start = DateTime.Parse(txtBeginDate.Text + " " + cmdBeginHour.SelectedValue.ToString() + ":" + cmdBeginMinute.SelectedValue.ToString() + ":" + "00");
else
start = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy") + " " + DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + "00");
end = DateTime.Parse(txtEndDate.Text + " " + DDL_EndHour.SelectedValue.ToString() + ":" + DDL_EndMin.SelectedValue.ToString() + ":" + "00");
/* Ensure these are "local" kind. I quote because
this is local time for user, not where the
site is hosted. */
start = DateTime.SpecifyKind(start, DateTimeKind.Local);
end = DateTime.SpecifyKind(end, DateTimeKind.Local);
/* Convert the start and end to UTC from
the timezone of the user with the
adjusted server to user timezone
offset. */
start = start.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
end = end.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
/* Specify this is UTC. */
start = DateTime.SpecifyKind(start, DateTimeKind.Utc);
end = DateTime.SpecifyKind(end, DateTimeKind.Utc);
DateTime showAfter = DateTime.MinValue;
showAfter = Convert.ToDateTime(_dataTable.Rows[position]["ShowAfter"]);
showAfter = DateTime.SpecifyKind(showAfter, DateTimeKind.Utc);
showAfter = showAfter.ToLocalTime();
现在这些都保存到数据库中
在我的WCF服务的服务器上,我拉取DataTable,但在返回要序列化的输出之前调整DateTime列,如下所示。
此步骤可能不是必需的,并且是以前尝试的剩余步骤。但我没有搞乱它,因为它起作用了
Int32 upperBound = (output.Rows.Count - 1);
DateTime showAfter = DateTime.MinValue;
DateTime showBefore = DateTime.MinValue;
for (Int32 i = upperBound; (i >= 0); i--)
{
showAfter = (DateTime)output.Rows[i]["ShowAfter"];
showBefore = (DateTime)output.Rows[i]["ShowBefore"];
showAfter = DateTime.SpecifyKind(showAfter, DateTimeKind.Utc);
showBefore = DateTime.SpecifyKind(showBefore, DateTimeKind.Utc);
output.Rows[i]["ShowAfter"] = showAfter;
output.Rows[i]["ShowBefore"] = showBefore;
}
最后在应用程序中显示反序列化时的正确本地化时间。我做以下几件事
Double selectedTimezone = 0D;
Double offsetTimezone = 0D;
TimeZoneInfo timezoneInfo = TimeZoneInfo.Local;
selectedTimezone = Double.Parse(DDL_EndTimezone.SelectedValue.ToString());
/* Obtain the timezone offset for server to user.
For me this is -1: -6 (CST) to -5 (EST) */
offsetTimezone = (timezoneInfo.BaseUtcOffset.TotalHours - selectedTimezone);
/* Parse the date time from the selected user
inputs. */
if (!chkSendMessageNow.Checked)
start = DateTime.Parse(txtBeginDate.Text + " " + cmdBeginHour.SelectedValue.ToString() + ":" + cmdBeginMinute.SelectedValue.ToString() + ":" + "00");
else
start = DateTime.Parse(DateTime.Now.ToString("MM/dd/yyyy") + " " + DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + "00");
end = DateTime.Parse(txtEndDate.Text + " " + DDL_EndHour.SelectedValue.ToString() + ":" + DDL_EndMin.SelectedValue.ToString() + ":" + "00");
/* Ensure these are "local" kind. I quote because
this is local time for user, not where the
site is hosted. */
start = DateTime.SpecifyKind(start, DateTimeKind.Local);
end = DateTime.SpecifyKind(end, DateTimeKind.Local);
/* Convert the start and end to UTC from
the timezone of the user with the
adjusted server to user timezone
offset. */
start = start.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
end = end.AddHours(offsetTimezone).AddHours(-1 * selectedTimezone);
/* Specify this is UTC. */
start = DateTime.SpecifyKind(start, DateTimeKind.Utc);
end = DateTime.SpecifyKind(end, DateTimeKind.Utc);
DateTime showAfter = DateTime.MinValue;
showAfter = Convert.ToDateTime(_dataTable.Rows[position]["ShowAfter"]);
showAfter = DateTime.SpecifyKind(showAfter, DateTimeKind.Utc);
showAfter = showAfter.ToLocalTime();
我尝试在不同的地方更改该类型,但没有任何效果
我尝试在将值提交到数据库之前设置DateTime.kind。然后我试着在应用程序上显示消息设置显示的时间跨度。在我看来,我必须在两者之间的某个地方设置一种。对我来说,这意味着返回数据表的WCF Web服务。我没有尝试遍历表并设置列种类,然后返回修改后的表。就个人而言,如果这能解决问题,这似乎是一项昂贵的工作。也许我弄错了,应该试一试。在数据库之前进行设置肯定不会起任何作用;该字段未保存。问题是在您从数据库中读取后,它将具有DateTime.Kind
等于Unspecified
,并且您希望它是Utc
(或者按照惯例)。所以,是的,你应该尝试一下(不会很贵)@wal一些关于这方面的东西<代码>Int32上限=(output.Rows.Count-1);对于(Int32 i=上限;(i>=0);i--){DateTime showAfter=(DateTime)output.Rows[i][“showAfter”];DateTime showBefore=(DateTime)output.Rows[i][“showBefore”];showAfter=DateTime.SpecifyKind(showAfter,DateTimeKind.Utc);showBefore=DateTime.SpecifyKind(showBefore,DateTimeKind.Utc);output.Rows[i][“showAfter”]=showAfter;output.Rows[i][“ShowBefore”]=ShowBefore;}不起作用:(在手机上显示时,时间仍然提前了一个小时。数据库显示上午9:20,手机显示上午10:20。数据库位于德克萨斯州(CMT),而我目前在纽约东部时间,因此差异是有意义的。