[Zope-dev] Re: Collector #1457: DateTime strftime() -- still broken

Steve Alexander steve@cat-box.net
Mon, 31 Jul 2000 23:31:14 +0100


support@digicool.com wrote:
> 
> Steve Alexander reported:
> 
> > This is a patch to address collector item 1455.
> >
> > Here's a working patch to make formatting of a DateTime instance work as generally expected, when you use
> >
> >   <dtml-var "_.DateTime()" fmt="%d %H %z">
> >
> > or whatever.
> >
> > It could be made more efficient by compiling the two regular expressions into class attributes. However, a bug in ts_regex stops it using compiled regular expressions in gsub.
> >
> > See the following URL for a description of the regex bug.
> >
> > http://lists.zope.org/pipermail/zope-dev/2000-July/006105.html
> >
> >
> 
> with patch:
> 
> > *** lib/python/DateTime/DateTime.old.py       Sun Jul 23 20:03:04 2000
> > --- lib/python/DateTime/DateTime.py   Mon Jul 24 14:01:37 2000
> > ***************
> > *** 1376,1382 ****
> >           return millis
> >
> >       def strftime(self, format):
> > !         return strftime(format, gmtime(self.timeTime()))
> >
> >       # General formats from previous DateTime
> >       def Date(self):
> > --- 1376,1385 ----
> >           return millis
> >
> >       def strftime(self, format):
> > !         diff=_tzoffset(self._tz, self._t)
> > !         format = ts_regex.gsub('\(^\|[^%]\)%Z', '\\1'+self._tz, format)
> > !         format = ts_regex.gsub('\(^\|[^%]\)%z', '\\1%+05d' % (diff/36), format)
> > !         return strftime(format, gmtime(self.timeTime()+diff))
> >
> >       # General formats from previous DateTime
> >       def Date(self):
> >
> 
> Thanks for the report. Per popular demand based on list
> feedback, strftime() now formats using the current timezone
> representation of the DateTime object (consistent with all
> of the other DT formatting methods).
> 
> For those who really needed it to format based on GMT, you
> can use the toZone() method to get a copy of the DateTime
> object represented in GMT and call the formatting methods
> on that object:
> 
>   <dtml-var "myDate.toZone('GMT')" fmt="%y, %m, %d">
> 
>   or
> 
>   <dtml-var "myDate.toZone('GMT').strftime('%y, %m, %d')">
> 
> -Brian

I just looked at the fix in CVS. I'm sad to report that it is still
broken.

Here's the patched method from CVS:

    def strftime(self, format):
        # Format the date/time using the *current timezone
representation*.
        jfirst = _julianday(self._year, 1, 1) - 1
        jtoday = _julianday(self._year, self._month, self._day)
        julian = jtoday - jfirst        
        time_info=(self._year, self._month, self._day,
                   self._hour, self._minute, self._nearsec,
                   (self._dayoffset + 6) % 7,
                   julian,
                   0)
        return strftime(format, time_info)


This gets time.strftime to format the time in the DateTime instance,
shifted by an appropriate amount. However, if you try and format with %z
or %Z to display the timezone information, it always comes out as GMT.
So, the implementation has gone from correct but not useful, to
generally useful but technically incorrect.

To see the problem, apply the patch and try this DTML snippet:

<dtml-let time1="_.DateTime('2000/07/23 14:03 BST')">
  Time: <dtml-var time1 fmt="%B %d, %Y %H:%M %Z"> <br>
  Time: <dtml-var "time1.fCommonZ()"> <br>
</dtml-let>



This prints out the following:

Time: July 23, 2000 14:03 GMT 
Time: July 23, 2000 2:03 pm GMT+1 

They are being presented as different times.
The first one should read "Time: July 23, 2000 14:03 GMT+1".

A solution is to replace the %Z and %z format substrings with correctly
calculated values, as in my original patch, included towards the start
of this message.

--
Steve Alexander
Software Engineer
Cat-Box limited
http://www.cat-box.net