The output of AbsoluteTimeDateFormat always uses a comma (",") as the
decimal separator for fractional seconds.
In many countries, the period (".") is used as the decimal separator.

Attached is a modified AbsoluteTimeDateFormat which determines the
decimal separator based on the Locale (either supplied or defaulted).
I added Locale-aware constructors which should support future I18N
efforts in the Layout classes.

In order to fully utilize this new AbsoluteTimeDateFormat, I had to
modify DateTimeDateFormat and ISO8601DateFormat constructors and 
format() methods.  These modified classes are also attached.

Another modification to DateTimeDateFormat and ISO8601DateFormat was
done so their date strings are created, at most, once per day rather
than the once per format() call or once per second that previously
existed.

I also modified ISO8601DateFormat to use a static final array of month
strings rather than the previous switch statement.  This should
provide a slight improvement to performance.

Finally, I've attached the output of a Compare program that shows
the differences between the original versions and the ones attached.

Mike McAngus
Associate Chief Engineer
Wendy's International
Knowledge Management
614-764-6776



Attachment: AbsoluteTimeDateFormat.java
Description: Binary data

Attachment: ISO8601DateFormat.java
Description: Binary data

Compare: (<)C:\Open 
Source\Originals\jakarta-log4j-1.2\org\apache\log4j\helpers\AbsoluteTimeDateFormat.java
 (3479 bytes)
   with: (>)C:\Open 
Source\MyChanges\jakarta-log4j-1.2\org\apache\log4j\helpers\AbsoluteTimeDateFormat.java
 (5010 bytes)

6c6,7
<  * distribution in the LICENSE.txt file.  */
---
>  * distribution in the LICENSE.txt file.
>  */
13a14
> import java.util.Locale;
16a18,19
> import java.text.DecimalFormat;
> import java.text.NumberFormat;
19,23c23,30
<    Formats a {@link Date} in the format "HH:mm:ss,SSS" for example,
<    "15:49:37,459".
< 
<    @author Ceki G&uuml;lc&uuml;
<    @author Andrew Vajoczki
---
>    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&uuml;lc&uuml;
>    @author Andrew Vajoczki    
32c39,40
<      value is <b>ABSOLUTE</b>.  */
---
>      value is <b>ABSOLUTE</b>.
>   */
49a57,62
>   /*
>    * Set default decimal separator.  One or the other has to be chosen, so
>    * for historical purposes we choose the comma.
>    */
>   private char decimalSeparator = ',';
> 
52a66
>     setDecimalSeparator(Locale.getDefault());
57a72,84
>     setDecimalSeparator(Locale.getDefault());
>   }
> 
>   public
>   AbsoluteTimeDateFormat(Locale locale) {
>     setCalendar(Calendar.getInstance(locale));
>     setDecimalSeparator(locale);
>   }
> 
>   public
>   AbsoluteTimeDateFormat(TimeZone timeZone, Locale locale) {
>     setCalendar(Calendar.getInstance(timeZone, locale));
>     setDecimalSeparator(locale);
63,64c91,99
<      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>
69c104
<     */
---
>    */
77c112,115
<     if ((now - millis) != previousTime) {
---
>     if ((now - millis) == previousTime) {
>       sbuf.append(previousTimeWithoutMillis);
>     }
>     else {
105c143
<       sbuf.append(',');
---
>       sbuf.append(decimalSeparator);
112,116d150
<     else {
<       sbuf.append(previousTimeWithoutMillis);
<     }
< 
< 
128a161,172
>      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();
>       }
>   }
> 
>   /**
Compare: (<)C:\Open 
Source\Originals\jakarta-log4j-1.2\org\apache\log4j\helpers\ISO8601DateFormat.java 
(3881 bytes)
   with: (>)C:\Open 
Source\MyChanges\jakarta-log4j-1.2\org\apache\log4j\helpers\ISO8601DateFormat.java 
(3620 bytes)

12a12
> import java.util.Locale;
20,21c21,23
<    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}.
35,36c37,44
<   public
<   ISO8601DateFormat() {
---
>   private static final String[] MONTHS = {"-01-","-02-","-03-",
>                                           "-04-","-05-","-06-",
>                                           "-07-","-08-","-09-",
>                                           "-10-","-11-","-12-"};
> 
>   public
>   ISO8601DateFormat() {
>     this(TimeZone.getDefault(), Locale.getDefault());
41,51c49,77
<     super(timeZone);
<   }
< 
<   static private long   lastTime;
<   static private char[] lastTimeString = new char[20];
< 
<   /**
<      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".
< 
<      @param sbuf the <code>StringBuffer</code> to write to
---
>     this(timeZone, Locale.getDefault());
>   }
> 
>   public
>   ISO8601DateFormat(Locale locale) {
>     this(TimeZone.getDefault(), locale);
>   }
> 
>   public
>   ISO8601DateFormat(TimeZone timeZone, Locale locale) {
>     super(timeZone, locale);
>     now = (Calendar)calendar.clone();
>   }
> 
>   private static Calendar now;
>   private static int      lastDate = 0;
>   private static char[]   lastDateString = new char[11]; // "yyyy-MM-dd "
> 
>   /**
>      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-Nov-06 15:49:37,459" for most
>      European and East European countries, or 
>      "1994-Nov-06 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
57,61c83,93
<     long now = date.getTime();
<     int millis = (int)(now % 1000);
< 
<     if ((now - millis) != lastTime) {
<       // We reach this point at most once per second
---
>     now.setTime(date);
> 
>     // Created comparison date in yyyyDDD format
>     int today = (1000 * now.get(Calendar.YEAR)) +
>                 now.get(Calendar.DAY_OF_YEAR);
> 
>     if (today == lastDate) {
>       sbuf.append(lastDateString);
>     }
>     else {
>       // We reach this point at most once per day
65c97
<       calendar.setTime(date);
---
>       lastDate = today;
69,90c101,106
<       int year =  calendar.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);
< 
<       int day = calendar.get(Calendar.DAY_OF_MONTH);
---
>       int year =  now.get(Calendar.YEAR);
>       sbuf.append(year);
> 
>       sbuf.append(MONTHS[Calendar.MONTH]);
> 
>       int day = now.get(Calendar.DAY_OF_MONTH);
94,99c110,125
< 
<       sbuf.append(' ');
< 
<       int hour = calendar.get(Calendar.HOUR_OF_DAY);
<       if(hour < 10) {
<       sbuf.append('0');
---
>       sbuf.append(' ');
> 
>       sbuf.getChars(start, sbuf.length(), lastDateString, 0);
>     }
> 
>     // Add the time to the date string.
>     return super.format(date, sbuf, fieldPosition);
>   }
> 
>   /**
>     This method does not do anything but return <code>null</code>.
>    */
>   public
>   Date parse(java.lang.String s, ParsePosition pos) {
>     return null;
>   }
101,144d127
<       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(',');
< 
<       // store the time string for next time to avoid recomputation
<       sbuf.getChars(start, sbuf.length(), lastTimeString, 0);
<       lastTime = now - millis;
<     }
<     else {
<       sbuf.append(lastTimeString);
<     }
< 
< 
<     if (millis < 100)
<       sbuf.append('0');
<     if (millis < 10)
<       sbuf.append('0');
< 
<     sbuf.append(millis);
<     return sbuf;
<   }
< 
<   /**
<     This method does not do anything but return <code>null</code>.
<    */
<   public
<   Date parse(java.lang.String s, ParsePosition pos) {
<     return null;
<   }
< }

Attachment: DateTimeDateFormat.java
Description: Binary data

Compare: (<)C:\Open 
Source\Originals\jakarta-log4j-1.2\org\apache\log4j\helpers\DateTimeDateFormat.java 
(1885 bytes)
   with: (>)C:\Open 
Source\MyChanges\jakarta-log4j-1.2\org\apache\log4j\helpers\DateTimeDateFormat.java 
(3296 bytes)

6c6,7
<  * distribution in the LICENSE.txt file.  */
---
>  * distribution in the LICENSE.txt file.
>  */
11a12
> import java.util.Locale;
18,19c20,22
<    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}.
30,31c33
<     super();
<     shortMonths = new DateFormatSymbols().getShortMonths();
---
>     this(TimeZone.getDefault(), Locale.getDefault());
36,44c38,67
<     this();
<     setCalendar(Calendar.getInstance(timeZone));
<   }
< 
<   /**
<      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".
< 
<      @param sbuf the string buffer to write to
---
>     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();
>     now = (Calendar)calendar.clone();
>   }
> 
>   private static Calendar now;
>   private static int      lastDate = 0;
>   private static char[]   lastDateString = new char[12]; // "dd MMM yyyy "
> 
>   /**
>      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
50,63c73,106
<     calendar.setTime(date);
< 
<     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(' ');
< 
---
>     now.setTime(date);
> 
>     // Created comparison date in yyyyDDD format
>     int today = (1000 * now.get(Calendar.YEAR)) +
>                 now.get(Calendar.DAY_OF_YEAR);
> 
>     if (today == lastDate) {
>       sbuf.append(lastDateString);
>     }
>     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.
> 
>       lastDate = today;
> 
>       int start = sbuf.length();
> 
>       int day = now.get(Calendar.DAY_OF_MONTH);
>       if(day < 10)
>         sbuf.append('0');
>       sbuf.append(day);
>       sbuf.append(' ');
>       sbuf.append(shortMonths[now.get(Calendar.MONTH)]);
>       sbuf.append(' ');
> 
>       int year =  now.get(Calendar.YEAR);
>       sbuf.append(year);
>       sbuf.append(' ');
> 
>       sbuf.getChars(start, sbuf.length(), lastDateString, 0);
>     }
> 
>     // Add the time to the date string.
--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to