Dear Jeff et al,
I am recovering a topic from the list archive, as I could finally give it a
serious test (on Sunday the clocks will change and the server is giving me
real answers I can check). The original thread is paste below.
After testing with real answers from the server here are my conclusions:
- The answers I receive are all in UTC format. Examples from the XML
response:
- 2010-10-30T14:00:00.000Z (Before clock change on Sunday)
- 2010-11-02T19:45:00.000Z (After clock change on Sunday)
Given that my timezone is CET (GMT+1 + Daylight Saving Time during the
summer), I would expect the following transformations back from suds (the
time is the only important part):
- 14:00 -> 16:00 (+2 added during parsing, because DST will still apply
on Sun, Oct 30th)
- 19:45 -> 20:45 (+1 added during parsing, because DST will no longer
apply on Tue, Nov 2nd)
But unfortunately I receive the following transformation:
- 14:00 -> 15:00 (+1 added ...) Wrong answer
- 19:45 -> 20:45 (+1 added ...) Right answer
The above seems to indicate that suds is finding out the right "offset" for
my timezone (+1) but it is not capable of detecting the DST settings (+1
now, +0 next week)
After having a look at the suds/sax/date.py module, I think the problem is
in the Timezone object. This object is the one responsible parsing the
timezone part (offset) and later returning the "adjustment". But it returns
a *blind adjustment*, because it returns an offset without taking into
account the date, and therefore without taking into account DST.
Of course I can compensate for that in my code, but I think the Timezone
object could and should handle it. And following my proposal from March, I
do also truly believe that objects could be returned being "Timezone aware"
by returning them with a "LocalTimezone object". The LocalTimezone class
below could be added to the "datetime" generated by suds.
The LocalTimezone class was adapted (small changes) from the Python
documentation and relies on the information of the underlying operating
system. The code is pasted below. Currently I am currently using this code
in my own application. A quick cure for suds woul be to include it in
suds/sax/date.py and add the following 2 lines at the beginning of
DateTime.__adjust: (I even told my system that we were already in November
where DST no longer applies):
dstDelta = LocalTimezone().dst(self.datetime)
self.datetime += dstDelta
The rest of the offset calculations can proceed as normal.
Code for "LocalTimezone" follows.
from datetime import datetime, timedelta, tzinfo
class LocalTimezone(tzinfo):
'''
System specific local timezone.
As seen in the Python docs (with mods)
'''
ZERO = timedelta(0)
STDOFFSET = timedelta(seconds=-_time.timezone)
if _time.daylight:
DSTOFFSET = timedelta(seconds=-_time.altzone)
else:
DSTOFFSET = STDOFFSET
DSTDIFF = DSTOFFSET - STDOFFSET
def utcoffset(self, dt):
'''
Return the offset to UTC (GMT) for the given datetime
@param dt: datetime to see offset against
@type dt: datetime
'''
if self._isdst(dt):
return LocalTimezone.DSTOFFSET
else:
return LocalTimezone.STDOFFSET
def dst(self, dt):
'''
Return the daylight savings offset for the given datetime
@param dt: datetime to see offset against
@type dt: datetime
'''
if self._isdst(dt):
return LocalTimezone.DSTDIFF
else:
return LocalTimezone.ZERO
def tzname(self, dt):
'''
Return the name of this timezone for the given datetime
@param dt: datetime to see offset against
@type dt: datetime
'''
return _time.tzname[self._isdst(dt)]
def _isdst(self, dt):
'''
Private function to find out if the system reports
to be in DST mode for the given datetime
@param dt: datetime to see offset against
@type dt: datetime
'''
tt = (dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second,
dt.weekday(), 0, -1)
stamp = _time.mktime(tt)
tt = _time.localtime(stamp)
return tt.tm_isdst > 0
Best regards
Daniel
----------------------------------------------------------------------------------------
*Daniel Rodriguez* danjrod at
gmail.com
<suds%40lists.fedoraproject.org?Subject=Re:%20%5BFedora-suds-list%5D%20Timezone-aware%20Datetime%20objects&In-Reply-To=%3C8ba9089f1003300650yed76596icfb55ae4e283f9c4%40mail.gmail.com%3E>
*Tue Mar 30 13:50:08 UTC 2010*
- Previous message: [Fedora-suds-list] Timezone-aware Datetime
objects<http://lists.fedoraproject.org/pipermail/suds/2010-March/00077...
- Next message: [Fedora-suds-list] Handling faults from Axis web
service<http://lists.fedoraproject.org/pipermail/suds/2010-March/00078...
- *Messages sorted by:* [ date
]<http://lists.fedoraproject.org/pipermail/suds/2010-March/date.html#780>
[ thread
]<http://lists.fedoraproject.org/pipermail/suds/2010-March/thread.html#780>
[ subject
]<http://lists.fedoraproject.org/pipermail/suds/2010-March/subject.html#780>
[ author
]<http://lists.fedoraproject.org/pipermail/suds/2010-March/author.html#780>
-
Hi Jeff,
Thanks for your answer. I think you followed perfectly by reading your
answer. I talk only about received objects. So far I didn't send any.
The issue (as I see it) is that the returned datetime is a "naive" object,
and we live in a world with timezones, daylight saving schemes. And Python
does not mix naive and timezone-aware objects.
The options you suggest:
a) Returning UTC objects. If there were a generic tz object describing this
timezone this would be the best approach. Since coordination of time has to
be referenced to UTC and the object could later be used with
"astimezone(xxx)" to return objects adapted to the timezone to be displayed
to users
b) Option in suds to apply a tz object for returned objects. This can be
possibly seen as an extension of a), since a general UTC tz object would be
replaced by the tz object supplied by the user. But thinking of applications
where the user can change the timezone, applying "astimezone(xxx)" would be
required again.
In my opinion "a" (given the existence of a generic tz object) is the
optimal.
And talking about a generic UTC tz object, this should be at least
definable, since UTC does not have DST settings (UTC is fixed, it is only
the countries moving away from it or getting closer to it with DST)
Best regards
Daniel
On Tue, Mar 30, 2010 at 15:00, Jeff Ortel <jortel at
redhat.com
<
https://admin.fedoraproject.org/mailman/listinfo/suds>> wrote:
* Hey Daniel,*>**>* Not sure I follow. Suds converts received
xs:datetime to a python datetime*>* object that has been adjusted to the local
timezone. When sending a*>* datetime, it is sent with TZ offset. Are you suggesting a
suds /option/*>* that would return the xs:datetime in UTC instead of the local TZ? Or,
an*>* options for suds to return a datetime object with tz_info set?*>**>*
Thanks,*>**>* Jeff*>**>**>* On 03/29/2010 02:52 AM, Daniel Rodriguez
wrote:*>**>>* Hi Jeff et al,*>>**>>* I was wondering what you and
others think about always returning*>>* timezone-aware datetime objects. The default
timezone would be UTC (GMT).*>>**>>* If the user of the library knows that the
default timezone for an object*>>* is not UTC he can then use "replace" to
change the timezone without*>>* changing the fields.*>>**>>* I
personally would see it as positive, since I find terrible to rebuild*>>* a datetime
object just to make the conversion from naive to*>>*
timezone-aware.*>>**>>* Best regards*>>**>>*
Daniel*>>**>>**>>**>>**>>*
_______________________________________________*>>* suds mailing list*>>* suds
at
lists.fedoraproject.org
<
https://admin.fedoraproject.org/mailman/listinfo/suds>*>>*
https://admin.fedoraproject.org/mailman/listinfo/suds*>>**>**>...
_______________________________________________*>* suds mailing list*>* suds at
lists.fedoraproject.org
<
https://admin.fedoraproject.org/mailman/listinfo/suds>*>*
https://admin.fedoraproject.org/mailman/listinfo/suds*>