2

我有这种情况:

服务器位于 (GMT +3) 时区

客户在 (GMT -5) 时区

服务器向客户端返回一个DateTime,假设它是“10JAN2013 00:00”并且 AFAIKDateTime没有附加时区信息。客户端的时间转换为客户端的时区,即“09JAN2013 16:00”!DTK 被指定为 DTK.Unspecified。

我的问题,如果DateTime没有时区信息,客户端如何知道服务器的时区?这让我很困惑!它是在 SOAP 的标头中发送的还是类似的?

4

1 回答 1

1

他们可能知道也可能不知道。当DateTime对象在客户端和服务器之间传递时,它们被序列化为双方都能理解的某种通用格式。在其中一些格式中,例如 XML,时区信息是通过网络发送的:如果您有DateTimewith DateTimeKind.Utc,则将在序列化日期后附加一个 'Z';forLocal时区会被添加,forUnspecified不会被添加,所以对方知道使用哪种格式。在其他格式中,例如 JSON,如果 kind 是 ,服务器将不会在日期时间发送任何内容Utc,但会为其他类型添加本地时区信息(对于Localand的 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();
    }
}
于 2013-01-03T03:37:21.967 回答