我有这种情况:
服务器位于 (GMT +3) 时区
客户在 (GMT -5) 时区
服务器向客户端返回一个DateTime
,假设它是“10JAN2013 00:00”并且 AFAIKDateTime
没有附加时区信息。客户端的时间转换为客户端的时区,即“09JAN2013 16:00”!DTK 被指定为 DTK.Unspecified。
我的问题,如果DateTime
没有时区信息,客户端如何知道服务器的时区?这让我很困惑!它是在 SOAP 的标头中发送的还是类似的?
他们可能知道也可能不知道。当DateTime
对象在客户端和服务器之间传递时,它们被序列化为双方都能理解的某种通用格式。在其中一些格式中,例如 XML,时区信息是通过网络发送的:如果您有DateTime
with DateTimeKind.Utc
,则将在序列化日期后附加一个 'Z';forLocal
时区会被添加,forUnspecified
不会被添加,所以对方知道使用哪种格式。在其他格式中,例如 JSON,如果 kind 是 ,服务器将不会在日期时间发送任何内容Utc
,但会为其他类型添加本地时区信息(对于Local
and的 JSON 格式没有区别Unspecified
;IIRC 接收方将此类信息视为Local
)。
如果您想查看网络上发生了什么,您可以运行下面的程序,同时拥有 Fiddler 等网络捕获工具,以查看客户端向服务器发送的内容。
public class StackOverflow_14132566
{
[ServiceContract]
public interface ITest
{
[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
DateTime Add10Hours(DateTime input, string description);
}
public class Service : ITest
{
public DateTime Add10Hours(DateTime input, string description)
{
return input.AddHours(10);
}
}
public static void Test()
{
string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "basic");
host.AddServiceEndpoint(typeof(ITest), new WebHttpBinding(), "web").Behaviors.Add(new WebHttpBehavior());
host.Open();
Console.WriteLine("Host opened");
ChannelFactory<ITest> factory = new ChannelFactory<ITest>(new BasicHttpBinding(), new EndpointAddress(baseAddress + "/basic"));
ITest proxy = factory.CreateChannel();
Console.WriteLine(proxy.Add10Hours(new DateTime(2013, 1, 2, 19, 29, 0, DateTimeKind.Utc), "XML, UTC"));
Console.WriteLine(proxy.Add10Hours(new DateTime(2013, 1, 2, 19, 29, 0, DateTimeKind.Local), "XML, Local"));
Console.WriteLine(proxy.Add10Hours(new DateTime(2013, 1, 2, 19, 29, 0, DateTimeKind.Unspecified), "XML, Unspecified"));
((IClientChannel)proxy).Close();
factory.Close();
factory = new ChannelFactory<ITest>(new WebHttpBinding(), new EndpointAddress(baseAddress + "/web"));
factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
proxy = factory.CreateChannel();
Console.WriteLine(proxy.Add10Hours(new DateTime(2013, 1, 2, 19, 29, 0, DateTimeKind.Utc), "JSON, UTC"));
Console.WriteLine(proxy.Add10Hours(new DateTime(2013, 1, 2, 19, 29, 0, DateTimeKind.Local), "JSON, Local"));
Console.WriteLine(proxy.Add10Hours(new DateTime(2013, 1, 2, 19, 29, 0, DateTimeKind.Unspecified), "JSON, Unspecified"));
((IClientChannel)proxy).Close();
factory.Close();
Console.Write("Press ENTER to close the host");
Console.ReadLine();
host.Close();
}
}