6

DateTimeOffsetを使用するいくつかの操作コントラクトを持つ.NETWCFサービスがあります。アイデアは、DSTとタイムゾーンとの混同を避けることです。

ただし、DateTimeOffsetを使用することはかなり非標準であり、たとえばJavaアプリケーションや古い.NETバージョンにバインドされた.NETアプリケーションに接続しようとすると頭痛の種になるため、結局のところ、DateTimeOffsetを使用することをお勧めします。 。

別の方法はUTCDateTimeを期待することですが、これは誰かがUTC時間を使用することを忘れて現地時間でサービスを呼び出すリスクをもたらします。クライアントは常に同じタイムゾーンにあるため、現地時間のDateTimeも期待できますが、これにより、DSTの変更に関して、微妙ではありますが古典的なあいまいさが残ります。

誰かがサービスインターフェイスでDateTimeOffsetに頭痛の種を持っていますか、それとも結局使用するのは比較的問題がありませんか?

4

2 に答える 2

9

現在、インフラストラクチャの一部を WCF に変更していますが、この未回答の質問に出くわし、試してみることにしました。:)

WCF がシリアル化する方法は、少し奇妙DateTimeDateTimeOffset思えます。次のサンプルが示すDateTimeように、他のプラットフォームで作業する場合は、 を使用する方が適切なオプションのように見えます。

using System;
using System.Runtime.Serialization;
using System.ServiceModel;

[ServiceContract]
public class DateTimeOffsetService
{
    [OperationContract]
    public Container DoWork()
    {
        return new Container
        {
            NowDateTime = DateTime.Now,
            UtcNowDateTime = DateTime.UtcNow,
            NowDateTimeOffset = DateTimeOffset.Now,
            UtcNowDateTimeOffset = DateTimeOffset.UtcNow
        };
    }
}

[DataContract]
public class Container
{
    [DataMember]
    public DateTime NowDateTime { get; set; }

    [DataMember]
    public DateTime UtcNowDateTime { get; set; }

    [DataMember]
    public DateTimeOffset NowDateTimeOffset { get; set; }

    [DataMember]
    public DateTimeOffset UtcNowDateTimeOffset { get; set; }
}

リクエストのレスポンス XML は次のとおりです。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header />
  <s:Body>
    <DoWorkResponse xmlns="http://tempuri.org/">
      <DoWorkResult xmlns:a="http://schemas.datacontract.org/2004/07/RD.MES.WcfService" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <a:NowDateTime>2012-03-23T15:59:47.8328698+01:00</a:NowDateTime>
        <a:NowDateTimeOffset xmlns:b="http://schemas.datacontract.org/2004/07/System">
          <b:DateTime>2012-03-23T14:59:47.8328698Z</b:DateTime>
          <b:OffsetMinutes>60</b:OffsetMinutes>
        </a:NowDateTimeOffset>
        <a:UtcNowDateTime>2012-03-23T14:59:47.8328698Z</a:UtcNowDateTime>
        <a:UtcNowDateTimeOffset xmlns:b="http://schemas.datacontract.org/2004/07/System">
          <b:DateTime>2012-03-23T14:59:47.8328698Z</b:DateTime>
          <b:OffsetMinutes>0</b:OffsetMinutes>
        </a:UtcNowDateTimeOffset>
      </DoWorkResult>
    </DoWorkResponse>
  </s:Body>
</s:Envelope>

私は GMT+01.00 タイムゾーンにいるので、値はほぼ正しいようです。なぜこのようになっているのですか?さて、WSDL はContainer次のように定義します。

<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/WcfService">
    <xs:import schemaLocation="http://localhost:3608/DateTimeOffsetService.svc?xsd=xsd3" namespace="http://schemas.datacontract.org/2004/07/System"/>
    <xs:complexType name="Container">
        <xs:sequence>
            <xs:element minOccurs="0" name="NowDateTime" type="xs:dateTime"/>
            <xs:element minOccurs="0" name="NowDateTimeOffset" type="q1:DateTimeOffset"/>
            <xs:element minOccurs="0" name="UtcNowDateTime" type="xs:dateTime"/>
            <xs:element minOccurs="0" name="UtcNowDateTimeOffset" type="q2:DateTimeOffset"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="Container" nillable="true" type="tns:Container"/>
</xs:schema>

そしてDateTimeOffset- WSDL では - 次のように定義されています。

<xs:schema elementFormDefault="qualified" targetNamespace="http://schemas.datacontract.org/2004/07/System">
    <xs:import schemaLocation="http://localhost:3608/DateTimeOffsetService.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
    <xs:complexType name="DateTimeOffset">
        <xs:annotation>
            <xs:appinfo>
                <IsValueType>true</IsValueType>
            </xs:appinfo>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="DateTime" type="xs:dateTime"/>
            <xs:element name="OffsetMinutes" type="xs:short"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="DateTimeOffset" nillable="true" type="tns:DateTimeOffset"/>
</xs:schema>

したがって、基本的にDateTimeは、標準としてシリアル化されxs:dateTime(正しいタイムゾーン コンポーネントを持っています) DateTimeOffset、非標準の複合型にシリアル化されます。これは、呼び出し元が正しく理解して処理する必要があります。

FWIW; これを見つけたので、DateTime実際に別のタイムゾーン オフセットを処理する必要がない限り、おそらく WCF インターフェイスに使用します。

現在、複雑な型を使用することを支持する唯一の理由は (複雑な型xs:dateTimeが持つすべての情報を含めることができるはずだからです!) とxs:dateTimeをシリアル化するために使用されたDateTime場合DateTimeOffset、WCF クライアントはどの型を使用すればよいか分からないということです。 .

于 2012-03-23T15:43:30.470 に答える
1

WCFサービスでDateTimeを使用する際の最大の頭痛の種は、WCFが現在xs:Dateをサポートしていないことです。この関連する質問とリンクされたConnectの提案を参照してください。

DateTimeOffsetは、この問題の解決にはなりません。

于 2012-02-07T07:29:22.343 に答える