Sorry for the delay. I finally have produced unified diffs for the modified classes. Hopefully, these will not transmit as in-line text (I added them as attachments after modifying some of my email settings).
I moved the DateFormat subclasses to their o.a.l.helpers package before running the diffs. -- Cheers, Mike McAngus [EMAIL PROTECTED]
cvs diff -u -r1.4 AbsoluteTimeDateFormat.java Index: AbsoluteTimeDateFormat.java =================================================================== RCS file: /home/cvspublic/jakarta-log4j/src/java/org/apache/log4j/helpers/AbsoluteTimeDateFormat.java,v retrieving revision 1.4 diff -u -r1.4 AbsoluteTimeDateFormat.java --- AbsoluteTimeDateFormat.java 17 Feb 2002 21:50:58 -0000 1.4 +++ AbsoluteTimeDateFormat.java 16 Jun 2002 03:51:27 -0000 @@ -3,24 +3,32 @@ * * This software is published under the terms of the Apache Software * License version 1.1, a copy of which has been included with this - * distribution in the LICENSE.txt file. */ + * distribution in the LICENSE.txt file. + */ package org.apache.log4j.helpers; import java.util.Date; import java.util.Calendar; import java.util.TimeZone; +import java.util.Locale; import java.text.FieldPosition; import java.text.ParsePosition; import java.text.DateFormat; +import java.text.DecimalFormat; +import java.text.NumberFormat; /** - Formats a {@link Date} in the format "HH:mm:ss,SSS" for example, - "15:49:37,459". - + Formats a {@link Date} in the format "HH:mm:ssdSSS", where the decimal + separator, 'd', is locale specific.<br> + For example, "15:49:37,459" for most European and East European countries, + or "15:49:37.459" for most of the Americas, most of the Middle East and + most of East Asia. + @author Ceki Gülcü - @author Andrew Vajoczki + @author Andrew Vajoczki + @author Mike McAngus @since 0.7.5 */ @@ -29,7 +37,8 @@ /** String constant used to specify {@link org.apache.log4j.helpers.AbsoluteTimeDateFormat} in layouts. Current - value is <b>ABSOLUTE</b>. */ + value is <b>ABSOLUTE</b>. + */ public final static String ABS_TIME_DATE_FORMAT = "ABSOLUTE"; /** @@ -46,27 +55,59 @@ */ public final static String ISO8601_DATE_FORMAT = "ISO8601"; + /* + formatString specifies the String that would have been used if + SimpleDateFormat were used to format the time instead of this + class. The decimal separator, and millisecond specification + for the time will be added when this class is instantiated. + */ + private String formatString = "HH:mm:ss"; + + /* + Set default decimal separator. One or the other has to be chosen, so + for historical purposes we choose the comma. + */ + private char decimalSeparator = ','; + public AbsoluteTimeDateFormat() { - setCalendar(Calendar.getInstance()); + this(TimeZone.getDefault(),Locale.getDefault()); } - + public AbsoluteTimeDateFormat(TimeZone timeZone) { - setCalendar(Calendar.getInstance(timeZone)); + this(timeZone,Locale.getDefault()); } - private static long previousTime; - private static char[] previousTimeWithoutMillis = new char[9]; // "HH:mm:ss." + public + AbsoluteTimeDateFormat(Locale locale) { + this(TimeZone.getDefault(),locale); + } + + public + AbsoluteTimeDateFormat(TimeZone timeZone, Locale locale) { + setCalendar(Calendar.getInstance(timeZone, locale)); + setDecimalSeparator(locale); + } + + private long previousTime; + private char[] previousTimeWithoutMillis = new char[9]; // "HH:mm:ssd" /** - Appends to <code>sbuf</code> the time in the format - "HH:mm:ss,SSS" for example, "15:49:37,459" + <p> + Appends to <code>sbuf</code> the millisecond timestamp in <code>Locale</code> + specific format. + </p> + <p> + For example, "HH:mm:ss,SSS" (e.g. "15:49:37,459") for most European + and East European countries, or "HH:mm:ss.SSS" (e.g. "15:49:37.459") + for most of the Americas, most of the Middle East and most of East Asia. + </p> @param date the date to format @param sbuf the string buffer to write to @param fieldPosition remains untouched - */ + */ public StringBuffer format(Date date, StringBuffer sbuf, FieldPosition fieldPosition) { @@ -74,7 +115,10 @@ long now = date.getTime(); int millis = (int)(now % 1000); - if ((now - millis) != previousTime) { + if ((now - millis) == previousTime) { + sbuf.append(previousTimeWithoutMillis); + } + else { // We reach this point at most once per second // across all threads instead of each time format() // is called. This saves considerable CPU time. @@ -82,53 +126,78 @@ calendar.setTime(date); int start = sbuf.length(); - + int hour = calendar.get(Calendar.HOUR_OF_DAY); if(hour < 10) { sbuf.append('0'); } sbuf.append(hour); sbuf.append(':'); - + int mins = calendar.get(Calendar.MINUTE); if(mins < 10) { sbuf.append('0'); } sbuf.append(mins); sbuf.append(':'); - + int secs = calendar.get(Calendar.SECOND); if(secs < 10) { sbuf.append('0'); } sbuf.append(secs); - sbuf.append(','); + sbuf.append(decimalSeparator); // store the time string for next time to avoid recomputation sbuf.getChars(start, sbuf.length(), previousTimeWithoutMillis, 0); - + previousTime = now - millis; } - else { - sbuf.append(previousTimeWithoutMillis); - } - - if(millis < 100) sbuf.append('0'); if(millis < 10) sbuf.append('0'); - + sbuf.append(millis); return sbuf; } /** + Returns the format string that would be used by <code>SimpleDateFormat</code> + if it was used to format the absolute time. + <p> + This method is protected because the format string is only of interest to the + parse methods of subclasses. + </p> + + @return The format <code>String</code>. + */ + protected + String getFormatString() { + return formatString; + } + + /** + Sets the decimalSeparator used for displaying Millisecond timestamps. + */ + private + void setDecimalSeparator(Locale locale) { + NumberFormat nf = NumberFormat.getInstance(locale); + if (nf instanceof DecimalFormat) { + decimalSeparator = + ((DecimalFormat)nf).getDecimalFormatSymbols().getDecimalSeparator(); + } + + // set the rest of the formatString + formatString += decimalSeparator + "SSS"; + } + + /** This method does not do anything but return <code>null</code>. */ public Date parse(String s, ParsePosition pos) { return null; - } + } } *****CVS exited normally with code 1*****
cvs diff -u -r1.4 DateTimeDateFormat.java Index: DateTimeDateFormat.java =================================================================== RCS file: /home/cvspublic/jakarta-log4j/src/java/org/apache/log4j/helpers/DateTimeDateFormat.java,v retrieving revision 1.4 diff -u -r1.4 DateTimeDateFormat.java --- DateTimeDateFormat.java 24 Apr 2002 01:16:13 -0000 1.4 +++ DateTimeDateFormat.java 16 Jun 2002 03:54:07 -0000 @@ -3,72 +3,147 @@ * * This software is published under the terms of the Apache Software * License version 1.1, a copy of which has been included with this - * distribution in the LICENSE.txt file. */ + * distribution in the LICENSE.txt file. + */ package org.apache.log4j.helpers; import java.util.Calendar; +import java.util.Locale; import java.util.TimeZone; import java.util.Date; import java.text.FieldPosition; import java.text.ParsePosition; import java.text.DateFormatSymbols; +import java.text.SimpleDateFormat; /** - Formats a {@link Date} in the format "dd MMM YYYY HH:mm:ss,SSS" for example, - "06 Nov 1994 15:49:37,459". + Provides a localized {@link Date} String by prepending the date formatted + as "dd MMM yyyy" to the time formatted according to the description in + {@link AbsoluteTimeDateFormat}. @author Ceki Gülcü + @author Mike McAngus + @since 0.7.5 */ public class DateTimeDateFormat extends AbsoluteTimeDateFormat { String[] shortMonths; + Locale myLocale; + + /* + If anything needs to parse a date that this class returns, then we will + use a SimpleDateFormat. The parser will be instantiated only if the + parse method is called for this instance. + */ + private SimpleDateFormat parser; public DateTimeDateFormat() { - super(); - shortMonths = new DateFormatSymbols().getShortMonths(); + this(TimeZone.getDefault(), Locale.getDefault()); } public DateTimeDateFormat(TimeZone timeZone) { - this(); - setCalendar(Calendar.getInstance(timeZone)); + this(timeZone, Locale.getDefault()); + } + + public + DateTimeDateFormat(Locale locale) { + this(TimeZone.getDefault(),locale); + } + + public + DateTimeDateFormat(TimeZone timeZone, Locale locale) { + super(timeZone, locale); + shortMonths = new DateFormatSymbols(locale).getShortMonths(); + myLocale = locale; } + private long now = 0; + private long tomorrow = 0; + private char[] todayString; // holds "dd MMM yyyy " + /** - Appends to <code>sbuf</code> the date in the format "dd MMM YYYY - HH:mm:ss,SSS" for example, "06 Nov 1994 08:49:37,459". + Appends to <code>sbuf</code> the date and time in + "dd MMM yyyy HH:mm:ssdSSS" format, where "d" is the + locale specific decimal separator. + For example, "06 Nov 1994 15:49:37,459" for most + European and East European countries, or + "06 Nov 1994 15:49:37.459" for most of the Americas, + most of the Middle East and most of East Asia. @param sbuf the string buffer to write to + @see AbsoluteTimeDateFormat */ public StringBuffer format(Date date, StringBuffer sbuf, FieldPosition fieldPosition) { - calendar.setTime(date); + now = date.getTime(); - int day = calendar.get(Calendar.DAY_OF_MONTH); - if(day < 10) - sbuf.append('0'); - sbuf.append(day); - sbuf.append(' '); - sbuf.append(shortMonths[calendar.get(Calendar.MONTH)]); - sbuf.append(' '); - - int year = calendar.get(Calendar.YEAR); - sbuf.append(year); - sbuf.append(' '); + if (now < tomorrow) { + sbuf.append(todayString); + } + else { + // We reach this point at most once per day + // across all threads instead of each time format() + // is called. This saves considerable CPU time. + + Calendar cal = (Calendar)calendar.clone(); + + int start = sbuf.length(); + + int day = cal.get(Calendar.DAY_OF_MONTH); + if(day < 10) + sbuf.append('0'); + sbuf.append(day); + sbuf.append(' '); + sbuf.append(shortMonths[cal.get(Calendar.MONTH)]); + sbuf.append(' '); + + int year = cal.get(Calendar.YEAR); + sbuf.append(year); + sbuf.append(' '); + + todayString = sbuf.substring(start).toCharArray (); + + // Set tomorrow to the timestamp of tomorrow at midnight. + cal.setTime(date); + cal.set(Calendar.HOUR,0); + cal.set(Calendar.MINUTE,0); + cal.set(Calendar.SECOND,0); + cal.set(Calendar.MILLISECOND,0); + cal.add(Calendar.DATE,1); + tomorrow = cal.getTime().getTime(); + } + // Add the time to the date string. return super.format(date, sbuf, fieldPosition); } /** - This method does not do anything but return <code>null</code>. - */ + Returns a <code>Date</code> for the supplied date/time (<code>text</code>) string + starting at the given parse position. + + <p>The <code>text</code> string <strong>MUST</strong> be in "dd MMM yyyy +HH:mm:ssdSSS" + format, where "d" is the locale specific decimal separator.</p> + + @param text The date/time string to be parsed + + @param pos On input, the position at which to start parsing; on + output, the position at which parsing terminated, or the + start position if the parse failed. + + @return A Date, or null if <code>text</code> could not be parsed + */ public - Date parse(java.lang.String s, ParsePosition pos) { - return null; + Date parse(String text, ParsePosition pos) { + if (parser == null) { + parser = new SimpleDateFormat("dd MMM yyyy " + super.getFormatString(), +myLocale); + } + + return parser.parse(text,pos); } } *****CVS exited normally with code 1*****
cvs diff -u -r1.6 ISO8601DateFormat.java Index: ISO8601DateFormat.java =================================================================== RCS file: /home/cvspublic/jakarta-log4j/src/java/org/apache/log4j/helpers/ISO8601DateFormat.java,v retrieving revision 1.6 diff -u -r1.6 ISO8601DateFormat.java --- ISO8601DateFormat.java 24 Apr 2002 01:16:13 -0000 1.6 +++ ISO8601DateFormat.java 16 Jun 2002 03:55:55 -0000 @@ -9,137 +9,147 @@ package org.apache.log4j.helpers; import java.util.Calendar; +import java.util.Locale; import java.util.TimeZone; import java.util.Date; import java.text.FieldPosition; import java.text.ParsePosition; +import java.text.SimpleDateFormat; // Contributors: Arndt Schoenewald <[EMAIL PROTECTED]> /** - Formats a {@link Date} in the format "YYYY-mm-dd HH:mm:ss,SSS" for example - "1999-11-27 15:49:37,459". + Provides a localized {@link Date} String by prepending the date formatted + as "yyyy-MM-dd" to the absolute time formatted according to the description + in {@link AbsoluteTimeDateFormat}. - <p>Refer to the <a + <p>Refer to the <a href=http://www.cl.cam.ac.uk/~mgk25/iso-time.html>summary of the International Standard Date and Time Notation</a> for more information on this format. @author Ceki Gülcü @author Andrew Vajoczki + @author Mike McAngus @since 0.7.5 */ public class ISO8601DateFormat extends AbsoluteTimeDateFormat { + /* + If anything needs to parse a date that this class returns, then we will + use a SimpleDateFormat. The parser will be instantiated only if the + parse method is called for this instance. + */ + private SimpleDateFormat parser; + + private static final String[] MONTHS = {"-01-","-02-","-03-", + "-04-","-05-","-06-", + "-07-","-08-","-09-", + "-10-","-11-","-12-"}; + public ISO8601DateFormat() { + this(TimeZone.getDefault(), Locale.getDefault()); } public ISO8601DateFormat(TimeZone timeZone) { - super(timeZone); + this(timeZone, Locale.getDefault()); + } + + public + ISO8601DateFormat(Locale locale) { + this(TimeZone.getDefault(), locale); + } + + public + ISO8601DateFormat(TimeZone timeZone, Locale locale) { + super(timeZone, locale); } - static private long lastTime; - static private char[] lastTimeString = new char[20]; + private long now = 0; + private long tomorrow = 0; + private char[] todayString = new char[11]; // holds "yyyy-MM-dd " /** - Appends a date in the format "YYYY-mm-dd HH:mm:ss,SSS" - to <code>sbuf</code>. For example: "1999-11-27 15:49:37,459". + Appends to <code>sbuf</code> the date and time in + "yyyy-MM-dd HH:mm:ssdSSS" format, where "d" is the + locale specific decimal separator. + For example, "1994-11-06 15:49:37,459" for most + European and East European countries, or + "1994-11-06 15:49:37.459" for most of the Americas, + most of the Middle East and most of East Asia. - @param sbuf the <code>StringBuffer</code> to write to + @param sbuf the string buffer to write to + @see AbsoluteTimeDateFormat */ public StringBuffer format(Date date, StringBuffer sbuf, FieldPosition fieldPosition) { - long now = date.getTime(); - int millis = (int)(now % 1000); + now = date.getTime(); - if ((now - millis) != lastTime) { - // We reach this point at most once per second + if (now < tomorrow) { + sbuf.append(todayString); + } + else { + // We reach this point at most once per day // across all threads instead of each time format() // is called. This saves considerable CPU time. - calendar.setTime(date); + Calendar cal = (Calendar)calendar.clone(); int start = sbuf.length(); - int year = calendar.get(Calendar.YEAR); + int year = cal.get(Calendar.YEAR); sbuf.append(year); - String month; - switch(calendar.get(Calendar.MONTH)) { - case Calendar.JANUARY: month = "-01-"; break; - case Calendar.FEBRUARY: month = "-02-"; break; - case Calendar.MARCH: month = "-03-"; break; - case Calendar.APRIL: month = "-04-"; break; - case Calendar.MAY: month = "-05-"; break; - case Calendar.JUNE: month = "-06-"; break; - case Calendar.JULY: month = "-07-"; break; - case Calendar.AUGUST: month = "-08-"; break; - case Calendar.SEPTEMBER: month = "-09-"; break; - case Calendar.OCTOBER: month = "-10-"; break; - case Calendar.NOVEMBER: month = "-11-"; break; - case Calendar.DECEMBER: month = "-12-"; break; - default: month = "-NA-"; break; - } - sbuf.append(month); + sbuf.append(MONTHS[cal.get(Calendar.MONTH)]); - int day = calendar.get(Calendar.DAY_OF_MONTH); + int day = cal.get(Calendar.DAY_OF_MONTH); if(day < 10) - sbuf.append('0'); + sbuf.append('0'); sbuf.append(day); - sbuf.append(' '); - int hour = calendar.get(Calendar.HOUR_OF_DAY); - if(hour < 10) { - sbuf.append('0'); - } - sbuf.append(hour); - sbuf.append(':'); - - int mins = calendar.get(Calendar.MINUTE); - if(mins < 10) { - sbuf.append('0'); - } - sbuf.append(mins); - sbuf.append(':'); + sbuf.getChars(start, sbuf.length(), todayString, 0); - int secs = calendar.get(Calendar.SECOND); - if(secs < 10) { - sbuf.append('0'); - } - sbuf.append(secs); + // Set tomorrow to the timestamp of tomorrow at midnight. + cal.setTime(date); + cal.set(Calendar.HOUR,0); + cal.set(Calendar.MINUTE,0); + cal.set(Calendar.SECOND,0); + cal.set(Calendar.MILLISECOND,0); + cal.add(Calendar.DATE,1); + tomorrow = cal.getTime().getTime(); + } - sbuf.append(','); + // Add the time to the date string. + return super.format(date, sbuf, fieldPosition); + } - // store the time string for next time to avoid recomputation - sbuf.getChars(start, sbuf.length(), lastTimeString, 0); - lastTime = now - millis; - } - else { - sbuf.append(lastTimeString); - } + /** + Returns a <code>Date</code> for the supplied date/time (<code>text</code>) string + starting at the given parse position. + <p>The <code>text</code> string <strong>MUST</strong> be in "yyyy-MM-dd +HH:mm:ssdSSS" + format, where "d" is the locale specific decimal separator.</p> - if (millis < 100) - sbuf.append('0'); - if (millis < 10) - sbuf.append('0'); + @param text The date/time string to be parsed - sbuf.append(millis); - return sbuf; - } + @param pos On input, the position at which to start parsing; on + output, the position at which parsing terminated, or the + start position if the parse failed. - /** - This method does not do anything but return <code>null</code>. + @return A Date, or null if <code>text</code> could not be parsed. */ - public - Date parse(java.lang.String s, ParsePosition pos) { - return null; - } -} + public + Date parse(String text, ParsePosition pos) { + if (parser == null) { + parser = new SimpleDateFormat("yyyy-MM-dd " + super.getFormatString()); + } + return parser.parse(text,pos); + } +} \ No newline at end of file *****CVS exited normally with code 1*****
cvs diff -u -r1.1 LogFileParser.java Index: LogFileParser.java =================================================================== RCS file: /home/cvspublic/jakarta-log4j/src/java/org/apache/log4j/lf5/util/LogFileParser.java,v retrieving revision 1.1 diff -u -r1.1 LogFileParser.java --- LogFileParser.java 26 Apr 2002 15:48:42 -0000 1.1 +++ LogFileParser.java 16 Jun 2002 04:00:45 -0000 @@ -15,10 +15,12 @@ import org.apache.log4j.lf5.viewer.LogFactor5ErrorDialog; import org.apache.log4j.lf5.viewer.LogFactor5LoadingDialog; +import org.apache.log4j.helpers.ISO8601DateFormat; + import javax.swing.*; import java.io.*; import java.text.ParseException; -import java.text.SimpleDateFormat; +import java.text.DateFormat; import java.util.Date; /** @@ -26,6 +28,7 @@ * * @author Brad Marlborough * @author Richard Hurst + * @author Mike McAngus */ // Contributed by ThoughtWorks Inc. @@ -51,7 +54,7 @@ //-------------------------------------------------------------------------- // Private Variables: //-------------------------------------------------------------------------- - private static SimpleDateFormat _sdf = new SimpleDateFormat("dd MMM yyyy HH:mm:ss,S"); + private static DateFormat _dateFormat = new ISO8601DateFormat(); private LogBrokerMonitor _monitor; LogFactor5LoadingDialog _loadDialog; private InputStream _in = null; @@ -195,14 +198,14 @@ } private long parseDate(String record) { - try { - String s = parseAttribute(DATE_DELIMITER, record); + String s = parseAttribute(DATE_DELIMITER, record); - if (s == null) { + if (s == null) { return 0; - } + } - Date d = _sdf.parse(s); + try { + Date d = _dateFormat.parse(s); return d.getTime(); } catch (ParseException e) { *****CVS exited normally with code 1*****
cvs diff -u -r1.1 FilteredLogTableModel.java Index: FilteredLogTableModel.java =================================================================== RCS file: /home/cvspublic/jakarta-log4j/src/java/org/apache/log4j/lf5/viewer/FilteredLogTableModel.java,v retrieving revision 1.1 diff -u -r1.1 FilteredLogTableModel.java --- FilteredLogTableModel.java 26 Apr 2002 15:48:43 -0000 1.1 +++ FilteredLogTableModel.java 16 Jun 2002 04:02:18 -0000 @@ -11,7 +11,10 @@ import org.apache.log4j.lf5.LogRecordFilter; import org.apache.log4j.lf5.PassingLogRecordFilter; +import org.apache.log4j.helpers.DateTimeDateFormat; + import javax.swing.table.AbstractTableModel; +import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; @@ -23,6 +26,7 @@ * * @author Richard Wan * @author Brent Sprecher + * @author Mike McAngus */ // Contributed by ThoughtWorks Inc. @@ -38,6 +42,7 @@ //-------------------------------------------------------------------------- protected LogRecordFilter _filter = new PassingLogRecordFilter(); + protected DateFormat _dateFormat = new DateTimeDateFormat(); protected List _allRecords = new ArrayList(); protected List _filteredRecords; protected int _maxNumberOfLogRecords = 5000; @@ -182,10 +187,10 @@ if (lr == null) { return "NULL Column"; } - String date = new Date(lr.getMillis()).toString(); + switch (col) { case 0: - return date + " (" + lr.getMillis() + ")"; + return _dateFormat.format(new Date(lr.getMillis())); case 1: return lr.getThreadDescription(); case 2: *****CVS exited normally with code 1*****
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>