2012-02-07 12 views
6

Mam usługę .NET WCF z kilkoma umowami operacyjnymi, które pobierają DateTimeOffset. Chodzi o to, aby uniknąć pomyłki z DST i strefami czasowymi.WCF DateTimeOffset compatibility

Jednak mam wątpliwości, że używanie DateTimeOffset jest dobrym pomysłem, ponieważ jest dość niestandardowe i może powodować bóle głowy u każdego, kto próbuje się połączyć z, powiedzmy, aplikacją Java lub aplikacją .NET związaną z starsza wersja .NET.

Alternatywą jest oczekiwanie czasu UTC, ale wiąże się to z ryzykiem, że ktoś zapomni użyć czasu UTC i zadzwoni do serwisu o czasie lokalnym. Mogę również oczekiwać lokalnego czasu DateTime, ponieważ klienci zawsze będą w tej samej strefie czasowej, ale pozostawia to pewną subtelną, ale klasyczną, niejednoznaczność dotyczącą zmian czasu letniego.

Czy ktoś ma historie o bólach głowy z DateTimeOffset w interfejsie usługi lub czy jest to w końcu względnie bezproblemowe?

+0

Odkładając na bok - DateTimeOffset jest rzeczywiście wspierany przez standard - ISO8601. Preferowany format serializacji wygląda następująco: "2012-02-07T07: 17: 00-05: 00". Ale nie jestem pewien, czy WCF kiedykolwiek to właściwie przyjęło, czy nie. –

Odpowiedz

1

IMHO Największym bólem głowy przy korzystaniu z DateTime z usługą WCF jest to, że WCF obecnie nie obsługuje xs: Data - patrz this related question i powiązane podpowiedzi Connect.

DateTimeOffset nie pomaga w tym problemie.

+0

Ale także problem DateTimeOffset nie jest tak naprawdę związany z tym. – hangy

8

Obecnie zmieniam niektóre z naszej infrastruktury do WCF i natknąłem się na to pytanie bez odpowiedzi i postanowiłem go wypróbować. :)

Sposób, w jaki WCF serializuje DateTime i DateTimeOffset, wydaje się nieco dziwny. Jak pokazuje poniższa próbki, stosując DateTime wygląda lepszym rozwiązaniem podczas pracy z innymi platformami:

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 odpowiedź życzenie:

<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> 

jestem w strefie czasowej GMT + 01.00 , więc wartości wydają się być w porządku. Dlaczego tak jest? Cóż, WSDL definiuje Container takiego:

<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> 

And DateTimeOffset - w WSDL - jest zdefiniowany jako:

<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> 

Więc zasadniczo DateTime jest szeregowane jako standardowy xs:dateTime (który ma właściwą strefę czasową komponent) i DateTimeOffset jest serializowany do niestandardowego typu złożonego, który wywołujący musiałby zrozumieć i obsługiwać poprawnie.

FWIW; Odkąd to odkryłem, prawdopodobnie użyję interfejsu DateTime dla interfejsu WCF, chyba że będę musiał zająć się różnymi przesunięciami stref czasowych.

Obecnie jedynym uzasadnieniem widziałem za pomocą typu złożonego (od xs:dateTime powinny móc zawierać wszystkie informacje, które to robi!) Jest to, że jeśli xs:dateTime zostały wykorzystane do serializacji DateTime i DateTimeOffset klient WCF nie miałby pojęcia, jakiego typu użyć.

Powiązane problemy