Bug 20380

Summary: AccessLogValve incorrectly calculates timezone
Product: Tomcat 4 Reporter: Jon Eaves <jon>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Severity: normal CC: jt
Priority: P3    
Version: 4.1.30   
Target Milestone: ---   
Hardware: All   
OS: All   

Description Jon Eaves 2003-05-31 05:15:50 UTC
AccessLogValve.java assumes that all timezones are exact multiples of an hour.
This doesn't work when you live in Adelaide (Australia) and other places around
the world.

When configured in that timezone, the log message looks like: - - [31/May/2003:14:26:23 9050] "GET /hello HTTP/1.1" 404 683

(Notice the 9050!)

I found this when I was working on a MonthlyAccessLogValve, and fixed it there.
This will presumably be the same in other parts of the logging functionality.

Here's some code that appears to correctly calculate the timezone for both
hour based, and half-hour based timezones.

     * Creating a time zone that is formatted as "+|-HHMM" is not
     * made easy by the Java classes. This provides a means of
     * creating a suitable formatted timezone.
    private String createTimeZoneFormat(TimeZone tz, Date now)
        int raw = (tz.getRawOffset() / 60000);
        if (tz.inDaylightTime(now))
            raw += 60;
        int hours = raw / 60;
        int mins = raw - (hours*60);

        StringBuffer sb = new StringBuffer();

        if (hours >=0)
            hours *= (-1);
            mins *= (-1);
        if (hours < 10)
        if (mins < 10)
        return sb.toString();
Comment 1 Tim Funk 2003-06-04 17:01:40 UTC
Fixed in tomcat5. If ok - will eventually backport to 4.1
Comment 2 James Telfer 2004-03-25 01:07:33 UTC
The offset still appears to be incorrect, though for a different reason that
that originally reported: the timezone offset output does not include daylight
saving. At the moment:

   x.x.x.x - - [25/Mar/2004:10:17:07 +0930] "GET / HTTP/1.1" 304 -

should be reported as:

   x.x.x.x - - [25/Mar/2004:10:17:07 +1030] "GET / HTTP/1.1" 304 -

Looking at org.apache.catalina.valves.AccessLogValve (4.1.30), line 1128 is:
   timeZone = calculateTimeZoneOffset(tz.getRawOffset());

I think this should use the TimeZone.getOffset() method instead, which returns
the offset including DST. AFAICS from the CVS history the getRawOffset() method
has always been used.

Considering the length of time this has been in the source, either (a) I'm
wrong, or (b) few people care.
Comment 3 Mark Thomas 2005-03-28 21:12:21 UTC
This has now been fixed in TC4.1.x and TC5.5.x

For the record getOffset() can't be used (at least in TC4) as it is a JDK 1.4
method and TC4 has to work with JDK 1.2