S
Symon R
This is a bit of a weird one that I haven't yet been able to solve - I'm
hoping someone out there can disprove my findings and tell me where I've
gone wrong!
I have designed a web service that accepts messages from .NET clients. The
web method call includes an object as one of it's parameters - this
reflected object has been given a property called "FutureDelivery" and
expects a DateTime value. The clients may be in different timezones from
the server.
Due to the nature of the application of which the web service is a part the
DateTime set in the object must remain immutable; if the consumer sets it to
10am in Paris then it must remain 10am at the receiving web service, even if
the web service resides in a different timezone from the consumer. Now by
remaining 10am I don't mean that I need them to share the same UTC - I want
10am as a fixed value that is recognized as 10am at the destination. I
realize that I could get away with this by having the property value as a
String instead, but this would leave me open to inconsistencies in submitted
values and would remove the advantages that the DateTime object provide for
the consumer.
Since I'm using a web service and all the communications between the
consumer and web service are in XML my first thought was that the web
service could modify the values in the incoming XML message and alter the
appropriate node. As a result I wrote a SOAPExtension to intercept the
incoming XML data before deserialization, locate the FutureDelivery nodes
and alter the timezone on the nodes. Since XML dateTimes are represented as
0001-01-01T00:00:00.0000000+1:00 (for example) I figured I could simply
strip the timezone component (+1:00 in this case) and replace it with
current the timezone offset for the current server location.
All well and good so far, but then I ran into a little stumbling block that
I have since been banging my head on...
I used System.Timezone.CurrentTimezone.GetUTCOffset(now) to obtain the
current timezone for the region. This value can change depending on the
current daylight savings status; for example, in Paris, France the offset is
+1:00 during standard time and +2:00 during daylight time, while in Sydney,
Australia its +10:00 during standard time and +11:00 during daylight time.
The problem I have is that these offsets to not appear to behave
consistently between regions and daylight settings.
To create an XML dateTime value that will be converted into a DateTime value
equaling DateTime.MinValue we need 0001-01-01T00:00:00.0000000 then have to
add the positive or negative UTCoffset in hours and subtract the delta if
daylight savings is in effect.
For example:
Dim tz As TimeSpan = System.TimeZone.CurrentTimeZone.GetUtcOffset(Now)
If System.TimeZone.CurrentTimeZone.IsDaylightSavingTime(Now) Then
tz =
tz.Subtract(System.TimeZone.CurrentTimeZone.GetDaylightChanges(Now.Year).Del
ta)
End If
At the end of this tz should hold a TimeSpan equaling the correct number of
hours for the offset. Convert this to a string as (+/-)hh:mm and add it to
the end of the string 0001-01-01T00:00:00.0000000 and you SHOULD be off and
running...
I got the following results:
Paris
CurrentTimezone default offset = +1 hour
Paris Standard time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = False
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 1 hour
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
TestValue = "0001-01-01T00:00:00.0000000+1:00"
CDate(TestValue) = #12:00:00 AM# (which equals DateTime.MinValue)
Paris Daylight time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = True
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 2 hours
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
....since 2 - 1 = 1...
TestValue = "0001-01-01T00:00:00.0000000+1:00"
CDate(TestValue )= #12:00:00 AM# (which equals DateTime.MinValue) *****YAY!
No problems yet...
Sydney:
CurrentTimezone default offset = + 10 hours
Sydney Standard time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = False
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 10 hours
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
TestValue = "0001-01-01T00:00:00.0000000+10:00"
CDate(TestValue)= #1:00:00 AM# ...****WHAT??? This should be midnight,
shouldn't it?
Sydney Daylight time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = True
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 11 hours
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
....since 11 - 1 = 10....
TestValue = "0001-01-01T00:00:00.0000000+10:00"
CDate(TestValue)= #1:00:00 AM# ...****WHAT??? This should be midnight,
shouldn't it?
For some reason the conversion of an XML dateTime into a DateTime seems to
think that the offset is one hour out!
Can someone explain this to me?? From everything I think I understand about
this the above values should always return #12:00:00 AM# The result of
these calculations cause data for Australia to be 1 hour out. This means
that I can't set up multiple web service nodes in multiple countries because
the timezone offset calculations only work in some of them.
Can anyone help me here?
Cheers,
Symon.
hoping someone out there can disprove my findings and tell me where I've
gone wrong!
I have designed a web service that accepts messages from .NET clients. The
web method call includes an object as one of it's parameters - this
reflected object has been given a property called "FutureDelivery" and
expects a DateTime value. The clients may be in different timezones from
the server.
Due to the nature of the application of which the web service is a part the
DateTime set in the object must remain immutable; if the consumer sets it to
10am in Paris then it must remain 10am at the receiving web service, even if
the web service resides in a different timezone from the consumer. Now by
remaining 10am I don't mean that I need them to share the same UTC - I want
10am as a fixed value that is recognized as 10am at the destination. I
realize that I could get away with this by having the property value as a
String instead, but this would leave me open to inconsistencies in submitted
values and would remove the advantages that the DateTime object provide for
the consumer.
Since I'm using a web service and all the communications between the
consumer and web service are in XML my first thought was that the web
service could modify the values in the incoming XML message and alter the
appropriate node. As a result I wrote a SOAPExtension to intercept the
incoming XML data before deserialization, locate the FutureDelivery nodes
and alter the timezone on the nodes. Since XML dateTimes are represented as
0001-01-01T00:00:00.0000000+1:00 (for example) I figured I could simply
strip the timezone component (+1:00 in this case) and replace it with
current the timezone offset for the current server location.
All well and good so far, but then I ran into a little stumbling block that
I have since been banging my head on...
I used System.Timezone.CurrentTimezone.GetUTCOffset(now) to obtain the
current timezone for the region. This value can change depending on the
current daylight savings status; for example, in Paris, France the offset is
+1:00 during standard time and +2:00 during daylight time, while in Sydney,
Australia its +10:00 during standard time and +11:00 during daylight time.
The problem I have is that these offsets to not appear to behave
consistently between regions and daylight settings.
To create an XML dateTime value that will be converted into a DateTime value
equaling DateTime.MinValue we need 0001-01-01T00:00:00.0000000 then have to
add the positive or negative UTCoffset in hours and subtract the delta if
daylight savings is in effect.
For example:
Dim tz As TimeSpan = System.TimeZone.CurrentTimeZone.GetUtcOffset(Now)
If System.TimeZone.CurrentTimeZone.IsDaylightSavingTime(Now) Then
tz =
tz.Subtract(System.TimeZone.CurrentTimeZone.GetDaylightChanges(Now.Year).Del
ta)
End If
At the end of this tz should hold a TimeSpan equaling the correct number of
hours for the offset. Convert this to a string as (+/-)hh:mm and add it to
the end of the string 0001-01-01T00:00:00.0000000 and you SHOULD be off and
running...
I got the following results:
Paris
CurrentTimezone default offset = +1 hour
Paris Standard time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = False
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 1 hour
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
TestValue = "0001-01-01T00:00:00.0000000+1:00"
CDate(TestValue) = #12:00:00 AM# (which equals DateTime.MinValue)
Paris Daylight time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = True
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 2 hours
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
....since 2 - 1 = 1...
TestValue = "0001-01-01T00:00:00.0000000+1:00"
CDate(TestValue )= #12:00:00 AM# (which equals DateTime.MinValue) *****YAY!
No problems yet...
Sydney:
CurrentTimezone default offset = + 10 hours
Sydney Standard time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = False
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 10 hours
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
TestValue = "0001-01-01T00:00:00.0000000+10:00"
CDate(TestValue)= #1:00:00 AM# ...****WHAT??? This should be midnight,
shouldn't it?
Sydney Daylight time:
System.Timezone.CurrentTimezone.IsDaylightSavingTime(Now) = True
System.Timezone.CurrentTimezone.GetUTCOffset(Now) = 11 hours
System.Timezone.CuttentTimezone.GetDayLightChanges(Now.Year).GetDelta.Hours
= 1
....since 11 - 1 = 10....
TestValue = "0001-01-01T00:00:00.0000000+10:00"
CDate(TestValue)= #1:00:00 AM# ...****WHAT??? This should be midnight,
shouldn't it?
For some reason the conversion of an XML dateTime into a DateTime seems to
think that the offset is one hour out!
Can someone explain this to me?? From everything I think I understand about
this the above values should always return #12:00:00 AM# The result of
these calculations cause data for Australia to be 1 hour out. This means
that I can't set up multiple web service nodes in multiple countries because
the timezone offset calculations only work in some of them.
Can anyone help me here?
Cheers,
Symon.