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: 127.0.0.1 - - [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) { sb.append('+'); } else { sb.append('-'); hours *= (-1); mins *= (-1); } if (hours < 10) { sb.append('0'); } sb.append(hours); if (mins < 10) { sb.append('0'); } sb.append(mins); return sb.toString(); }
Fixed in tomcat5. If ok - will eventually backport to 4.1
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.
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