msbyuva
msbyuva

Reputation: 3615

Date Conversion issue from webservice

I am consuming a Web Service which will return datetime fields in response object.

My reference.cs file has,

private System.DateTime timestampField;

public System.DateTime Timestamp {
    get {
        return this.timestampField;
    }
    set {
        this.timestampField = value;
    }
}

In SOAP UI when I called the service I see it's returning as 2014-06-09T21:24:56+00:00 , 2014-06-17T05:42:00-04:00

I have different Offsets for Different values..

But from my .NET App when I am calling it's converting to some other value as 6/9/2014 5:24:56 PM but it should be whose actual value is 6/9/2014 9:24 pm.

How can I fix this?

Upvotes: 1

Views: 3905

Answers (2)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241525

When you consume a SOAP web service that uses xsd:dateTime, Visual Studio will always create the client proxy class using a DateTime.

  • If there is no offset in the data, the values will come across with DateTimeKind.Unspecified.

  • If instead of an offset, the Z specifier is sent, then the values will come through with DateTimeKind.Utc.

  • If there is any offset at all, then the values come through with DateTimeKind.Local. Even when the offset is zero. Whatever the offset is, it is applied, and then the value is converted to local time. Essentially, it calls .ToLocalTime() internally.

This kind of stinks, but the easiest way to deal with it is to convert back to UTC using .ToUniversalTime(), or convert to another time zone using the TimeZoneInfo object.

Thanks to the hidden "4th kind", you can safely convert from local back to UTC without ambiguity. (The offset from the original value will disambiguate.)

As far as I know, there is no way to get it to create a DateTimeOffset instead. That would be ideal. However, if you really want to dive deep, you may be able to get it to ignore the offset completely - though that's not necessarily the best idea.

Also, it's worth mentioning that if you were to try to create your own service and expose a DateTimeOffset type directly - you'd run into problems. There isn't a mapping from DateTimeOffset back to xsd:dateTime or any of the other XML Schema data types used by SOAP. Instead, you get a custom complex type in the schema, and the data doesn't get passed along at all. On the client, instead of receiving a System.DateTimeOffset, you get a YourServiceReference.DateTimeOffset object that doesn't do anything at all. It's unfortunate, because it should be great advice to use DateTimeOffset in a public-facing API, but it simply doesn't work. At least not for SOAP/XML. Things are much better in the REST/JSON world.

Upvotes: 4

msbyuva
msbyuva

Reputation: 3615

This is what I did, not sure if it's the efficient way..

I had different offset values for different time values and I don't know the timezone from the time field value... what I did is

I converted the time field value to string and got the offset using sub string and applied that to the UTC of time field value

     TimeSpan offSetSpan = new TimeSpan();
          string dt = TimestampValue;
          string offset = TimestampValue.Substring(trackevent.Timestamp.Length - 6,6);

          if (offset != "+00:00" && offset != "-00:00")
                                {
                                    offSetSpan = TimeSpan.Parse(offset.Trim());
                                }
Console.WriteLine("Offset Timestamp: {0}", Convert.ToDateTime(TimestampValue).ToUniversalTime() + offSetSpan);

Upvotes: 0

Related Questions