jean-frederic clere wrote: > Y.Uzumasa wrote: > >> Hi! I made a patch for the strftime(3) log format because I read a >> comment on the org.apache.catalina.util.Strftime. >> Would someone evaluate and apply it? >> Regards. >> http://www.mars.co.jp/dev/tomcat/StrftimeFormat.java > > a diff -u old_file new_file would be great.
I attached 'patchfile.txt' Thanks. -- Yoshinori Uzumasa
--- jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/util/StrftimeFormat.java 2004-04-22 15:28:47.000000000 +0900 +++ - 2004-04-22 16:12:02.306726000 +0900 @@ -1,527 +0,0 @@ -/* - * Copyright 1999,2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.catalina.util; - -import java.text.DateFormatSymbols; -import java.text.FieldPosition; -import java.text.SimpleDateFormat; -import java.util.Map; -import java.util.Calendar; -import java.util.Collections; -import java.util.Date; -import java.util.Locale; - -/** - * Converts dates to strings using the same format specifiers as strftime. - * <pre> - * %a The abbreviated weekday name according to the current locale. - * %A The full weekday name according to the current locale. - * %b The abbreviated month name according to the current locale. - * %B The full month name according to the current locale. - * %c The preferred date and time representation for the current - * locale. - * %C The century number (year/100) as a 2-digit integer. (SU) - * %d The day of the month as a decimal number (range 01 to 31). - * %D Equivalent to %m/%d/%y. (Yecch - for Americans only. Americans - * should note that in other countries %d/%m/%y is rather common. - * This means that in international context this format is ambigu- - * ous and should not be used.) (SU) - * %e Like %d, the day of the month as a decimal number, but a leading - * zero is replaced by a space. (SU) - * %E Modifier: use alternative format, see below. (SU) - * %F Equivalent to %Y-%m-%d (the ISO 8601 date format). (C99) - * %G The ISO 8601 year with century as a decimal number. The 4-digit - * year corresponding to the ISO week number (see %V). This has - * the same format and value as %y, except that if the ISO week - * number belongs to the previous or next year, that year is used - * instead. (TZ) - * %g Like %G, but without century, i.e., with a 2-digit year (00-99). - * (TZ) - * %h Equivalent to %b. (SU) - * %H The hour as a decimal number using a 24-hour clock (range 00 to - * 23). - * %I The hour as a decimal number using a 12-hour clock (range 01 to - * 12). - * %j The day of the year as a decimal number (range 001 to 366). - * %k The hour (24-hour clock) as a decimal number (range 0 to 23); - * single digits are preceded by a blank. (See also %H.) (TZ) - * %l The hour (12-hour clock) as a decimal number (range 1 to 12); - * single digits are preceded by a blank. (See also %I.) (TZ) - * %m The month as a decimal number (range 01 to 12). - * %M The minute as a decimal number (range 00 to 59). - * %n A newline character. (SU) - * %O Modifier: use alternative format, see below. (SU) - * %p Either `AM' or `PM' according to the given time value, or the - * corresponding strings for the current locale. Noon is treated - * as `pm' and midnight as `am'. - * %P Like %p but in lowercase: `am' or `pm' or a corresponding string - * for the current locale. (GNU) - * %r The time in a.m. or p.m. notation. In the POSIX locale this is - * equivalent to `%I:%M:%S %p'. (SU) - * %R The time in 24-hour notation (%H:%M). (SU) For a version includ- - * ing the seconds, see %T below. - * %s The number of seconds since the Epoch, i.e., since 1970-01-01 - * 00:00:00 UTC. (TZ) - * %S The second as a decimal number (range 00 to 61). - * %t A tab character. (SU) - * %T The time in 24-hour notation (%H:%M:%S). (SU) - * %u The day of the week as a decimal, range 1 to 7, Monday being 1. - * See also %w. (SU) - * %U The week number of the current year as a decimal number, range - * 00 to 53, starting with the first Sunday as the first day of - * week 01. See also %V and %W. - * %V The ISO 8601:1988 week number of the current year as a decimal - * number, range 01 to 53, where week 1 is the first week that has - * at least 4 days in the current year, and with Monday as the - * first day of the week. See also %U and %W. (SU) - * %w The day of the week as a decimal, range 0 to 6, Sunday being 0. - * See also %u. - * %W The week number of the current year as a decimal number, range - * 00 to 53, starting with the first Monday as the first day of - * week 01. - * %x The preferred date representation for the current locale without - * the time. - * %X The preferred time representation for the current locale without - * the date. - * %y The year as a decimal number without a century (range 00 to 99). - * %Y The year as a decimal number including the century. - * %z The time-zone as hour offset from GMT. Required to emit - * RFC822-conformant dates (using "%a, %d %b %Y %H:%M:%S %z"). - * (GNU) - * %Z The time zone or name or abbreviation. - * %+ The date and time in date(1) format. (TZ) - * %% A literal `%' character. - * </pre> - * - * @author Yoshinori Uzumasa - * @version $Revision$, $Date$ - * @see org.apache.catalina.util.Strftime - */ -public class StrftimeFormat extends SimpleDateFormat { - - /** strftime(3) - SimpleDateFormat pattern mapping */ - private static final Map simples = translateSimples(); - /** SimpleDateFormat - strftime(3) pattern mapping */ - private static final Map strftimes = translateStrftimes(); - - private static Map translateSimples() { - Map map = new java.util.HashMap(41); - - // NOTE: the SimpleDateFormat pattern - map.put("a", "EEE"); - map.put("A", "EEEE"); - map.put("b", "MMM"); - map.put("B", "MMMM"); - map.put("c", "EEE MMM d HH:mm:ss yyyy"); - map.put("d", "dd"); - map.put("D", "MM/dd/yy"); - map.put("F", "yyyy-MM-dd"); - map.put("g", "yy"); - map.put("G", "yyyy"); - map.put("h", "MMM"); - map.put("H", "HH"); - map.put("I", "hh"); - map.put("j", "DDD"); - map.put("m", "MM"); - map.put("M", "mm"); - map.put("n", "\n"); - map.put("p", "a"); - map.put("r", "hh:mm:ss a"); - map.put("R", "HH:mm"); - map.put("S", "ss"); - map.put("t", "\t"); - map.put("T", "HH:mm:ss"); - map.put("V", "ww"); - map.put("X", "HH:mm:ss"); - map.put("y", "yy"); - map.put("Y", "yyyy"); - map.put("Z", "z"); - map.put("z", "Z"); - - map.put("%", "%%"); - - // NOTE: There's no way to specify this with SimpleDateFormat - // @see format(Date, StringBuffer, FieldPosition) - map.put("C", "%C"); - map.put("e", "%e"); - map.put("k", "%k"); - map.put("l", "%l"); - map.put("P", "%P"); - map.put("s", "%s"); - map.put("u", "%u"); - map.put("U", "%U"); - map.put("w", "%w"); - map.put("W", "%W"); - - // PENDING: "MM/dd/yy" is 'US' locale. - map.put("x", "MM/dd/yy"); - - return Collections.unmodifiableMap(map); - } - - private static Map translateStrftimes() { - Map map = new java.util.HashMap(23); - map.put("EEE", "a"); - map.put("EEEE", "A"); - map.put("MMM", "b"); - map.put("MMMM", "B"); - map.put("dd", "d"); - map.put("yy", "y"); - map.put("yyyy", "Y"); - map.put("H", ".1H"); - map.put("HH", "H"); - map.put("MMM", "h"); - map.put("hh", "I"); - map.put("DDD", "j"); - map.put("HH", "k"); - map.put("M", ".1m"); - map.put("MM", "m"); - map.put("mm", "M"); - map.put("\n", "n"); - map.put("a", "p"); - map.put("ss", "S"); - map.put("\t", "t"); - map.put("ww", "V"); - map.put("z", "Z"); - map.put("Z", "z"); - - return Collections.unmodifiableMap(map); - } - - private static boolean beginQuote(StringBuffer buff, boolean inQuote) { - if (!inQuote) - buff.append('\''); - - return true; - } - - private static boolean endQuote(StringBuffer buff, boolean inQuote) { - if (inQuote) - buff.append('\''); - - return false; - } - - private static void appendChar(StringBuffer buff, char c) { - if (c == '\'') - buff.append(c); - - buff.append(c); - } - - /** - * Returns the SimpleDateFormat form of the given strftime pattern. This - * does not mimic strftime perfectly. - * - * @param strftimePattern the strftime pattern - * @return the SimpleDateFormat pattern - */ - private static String convertSimple(String strftimePattern) { - final int length = strftimePattern.length(); - StringBuffer buff = new StringBuffer((int) (length * 1.5f)); - boolean inQuote = false; - - for (int i = 0; i < length; i++) { - char c0 = strftimePattern.charAt(i); - if (c0 != '%') { - if (c0 != '\'') - inQuote = beginQuote(buff, inQuote); - - appendChar(buff, c0); - continue; - } - - if (++i >= length) { - inQuote = beginQuote(buff, inQuote); - appendChar(buff, c0); - break; - } - - String pattern; - char c1 = strftimePattern.charAt(i); - char c2 = 0; - if (c1 == 'O' || c1 == 'E') { - if (++i >= length) - break; - - c2 = strftimePattern.charAt(i); - pattern = (String) simples.get(String.valueOf(c2)); - // PENDING: - // } else if (c1 == '.') { - } else { - pattern = (String) simples.get(String.valueOf(c1)); - } - - if (pattern == null) { - inQuote = beginQuote(buff, inQuote); - buff.append('%'); - appendChar(buff, c1); - if (c2 != 0) - appendChar(buff, c2); - } else if (pattern.startsWith("%")) { - inQuote = beginQuote(buff, inQuote); - buff.append(pattern); - } else { - inQuote = endQuote(buff, inQuote); - buff.append(pattern); - } - } - - endQuote(buff, inQuote); - - return new String(buff); - } - - /** - * Returns the strftime form of the given SimpleDateFormat pattern. - * - * @param simplePattern the SimpleDateFormat pattern - * @return the strftime pattern - */ - public static String convertStrftime(String simplePattern) { - final int length = simplePattern.length(); - StringBuffer buff = new StringBuffer(length); - StringBuffer buffShort = new StringBuffer(4); - - for (int i = 0; i < length; i++) { - char c0 = simplePattern.charAt(i); - switch (c0) { - case '%': - buff.append("%%"); - break; - case '\'': - char c1; - // NOTE: If quotation marks continue - if (++i < length) { - c1 = simplePattern.charAt(i); - if (c1 == '\'') { - buff.append('\''); - break; - } - } else { - break; - } - - // NOTE: It reads to the following quotation marks. - for (; i < length; i++) { - c1 = simplePattern.charAt(i); - if (c1 == '\'') { - break; - } else if (c1 == '%') { - buff.append("%%"); - } else { - buff.append(c1); - } - } - break; - case 'G': - case 'y': - case 'M': - case 'w': - case 'W': - case 'D': - case 'd': - case 'F': - case 'E': - case 'a': - case 'H': - case 'k': - case 'K': - case 'h': - case 'm': - case 's': - case 'S': - case 'z': - case 'Z': - // NOTE: as long as the same character continues. - buffShort.setLength(0); - for (; i < length; i++) { - c1 = simplePattern.charAt(i); - if (c1 != c0) { - i--; - break; - } - - buffShort.append(c1); - } - - if (buffShort.length() > 0) { - String sp = new String(buffShort); - String st = (String) strftimes.get(sp); - if (st != null) { - buff.append('%'); - buff.append(st); - } else { - buff.append(sp); - } - } - break; - default: - buff.append(c0); - break; - } - } - - return new String(buff); - } - - /** the strftime(3) pattern */ - private String strftimePattern; - - /** - * Constructs a StrftimeFormat using the default pattern and date format - * symbols for the default locale. - */ - public StrftimeFormat() { - super(); - this.strftimePattern = convertStrftime(super.toPattern()); - } - - /** - * Constructs a StrftimeFormat using the given pattern and the default date - * format symbols for the default locale. - * - * @param strftimePattern the strftime pattern - */ - public StrftimeFormat(String strftimePattern) { - this(strftimePattern, Locale.getDefault()); - } - - /** - * Constructs a StrftimeFormat using the given pattern and the default date - * format symbols for the default locale. - * - * @param strftimePattern the strftime pattern - * @param locale the locale whose date format symbols should be used - */ - public StrftimeFormat(String strftimePattern, Locale locale) { - super(convertSimple(strftimePattern), locale); - this.strftimePattern = strftimePattern; - } - - /** - * Constructs a StrftimeFormat using the given pattern and the default date - * format symbols for the given locale. - * - * @param strftimePattern the strftime pattern - * @param symbols the date format symbols to be used for formatting - */ - public StrftimeFormat(String strftimePattern, DateFormatSymbols symbols) { - super(convertSimple(strftimePattern), symbols); - this.strftimePattern = strftimePattern; - } - - // OVERRIDE: java.text.SimpleDateFormat - /** - * - * @param date the date-time value to be formatted into a date-time string. - * @param toAppendTo where the new date-time text is to be appended. - * @param pos the formatting position. On input: an alignment field, if - * desired. On output: the offsets of the alignment field. - * @return the formatted date/time string. - */ - public StringBuffer format(Date date, StringBuffer toAppendTo, - FieldPosition pos) { - StringBuffer buff = super.format(date, toAppendTo, pos); - calendar.setTime(date); - - for (int i = 0; i < buff.length(); i++) { - char c0 = buff.charAt(i); - if (c0 != '%') - continue; - - if (++i >= buff.length()) - break; - - char c1 = buff.charAt(i); - String value; - if (c1 == '%') { - value = "%"; - } else if (c1 == 'C') { - value = String.valueOf(calendar.get(Calendar.YEAR) / 100); - } else if (c1 == 's') { - value = String.valueOf(date.getTime()); - } else if (c1 == 'e') { - int d = calendar.get(Calendar.DAY_OF_MONTH); - value = (d < 10) ? (" " + d): String.valueOf(d); - } else if (c1 == 'k') { - int h = calendar.get(Calendar.HOUR_OF_DAY); - value = (h < 10) ? (" " + h): String.valueOf(h); - } else if (c1 == 'l') { - int h = calendar.get(Calendar.HOUR); - value = (h < 10) ? (" " + h): String.valueOf(h); - } else if (c1 == 'P') { - String backup = super.toLocalizedPattern(); - super.applyLocalizedPattern("a"); - value = super.format(date).toLowerCase(); - super.applyLocalizedPattern(backup); - } else if (c1 == 'u' || c1 == 'w') { - int w = calendar.get(Calendar.DAY_OF_WEEK) - 1; - if (c1 == 'w' && w == 0) - w = 7; - - value = String.valueOf(w); - } else if (c1 == 'U' || c1 == 'W') { - int backup1 = calendar.getFirstDayOfWeek(); - int backup2 = calendar.getMinimalDaysInFirstWeek(); - - calendar.setFirstDayOfWeek((c1 == 'U') ? Calendar.SUNDAY: - Calendar.MONDAY); - calendar.setMinimalDaysInFirstWeek(1); - int w = calendar.get(Calendar.WEEK_OF_YEAR); - value = (w < 10) ? ("0" + w): String.valueOf(w); - - calendar.setFirstDayOfWeek(backup1); - calendar.setMinimalDaysInFirstWeek(backup2); - } else { - continue; - } - - buff.replace((i - 1), (i + 1), value); - i += (value.length() - 2); - } - - return buff; - } - - // OVERRIDE: java.text.SimpleDateFormat - public void applyLocalizedPattern(String strftimePattern) { - super.applyLocalizedPattern(convertSimple(strftimePattern)); - this.strftimePattern = strftimePattern; - } - - // OVERRIDE: java.text.SimpleDateFormat - public void applyPattern(String strftimePattern) { - super.applyPattern(convertSimple(strftimePattern)); - this.strftimePattern = strftimePattern; - } - - // OVERRIDE: java.text.SimpleDateFormat - public String toLocalizedPattern() { - // PENDING: - return strftimePattern; - } - - // OVERRIDE: java.text.SimpleDateFormat - public String toPattern() { - return strftimePattern; - } - - public String toSimplePattern() { - return super.toPattern(); - } -}
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]