Hi Daniel,

 

Check out ticket #353 (https://fedorahosted.org/suds/ticket/353) where I have provided a complete patch that I hope will fix this issue. I can't remember which revision I made the patch against, if it doesn't apply cleanly I can make another. It includes a class that is extremely similar to your LocalTimezone class below.

 

I actually use this patch in production systems, and it works well for me. Hopefully it, or a similar patch, can make it into the next release.

 

Kind regards,

Glen

 

 

GLEN WALKER

KORDIA

ENGINEER PROGRAMMER

Kordia Ltd | DDI. +64 4 914 8058 | M. +64 21 936 627

 

 

From: suds-bounces@lists.fedoraproject.org [mailto:suds-bounces@lists.fedoraproject.org] On Behalf Of Daniel Rodriguez
Sent: Friday, 29 October 2010 7:53 p.m.
To: suds
Subject: [Fedora-suds-list] Timezone aware objects - Revisited

 

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:

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

But unfortunately I receive the following transformation:

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 
Tue Mar 30 13:50:08 UTC 2010

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> 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
>> 
> 
> 
> _______________________________________________
> suds mailing list
> suds at lists.fedoraproject.org
> https://admin.fedoraproject.org/mailman/listinfo/suds
> 
This email and attachments: are confidential; may be protected by privilege and copyright; if received in error may not be used, copied, or kept; are not guaranteed to be virus-free; may not express the views of Kordia(R); do not designate an information system; and do not give rise to any liability for Kordia(R).