Hi,
I have added some lines of code to I18nTransformer.java
and tested. It is attached to this mail.
I hope this is useful not only to me ;-)

1) before: <i18n:date ... />   -> date and time
   now: <i18n:date ... />      -> only date -> incompatibility
                 -> new URI: http://apache.org/cocoon/i18n/2.1
        <i18n:time ... />      -> time
        <i18n:date-time ... /> -> date and time
2) the src-pattern and pattern attributes for date and time
   recognizes now also:"short", "medium", "long" and "full"
   in addition to a regular pattern
3) fixed a bug in <i18n:number/> wich caused wrong output if the
   value was given as text and not as value="...":
   <i18n:number sub-type="currency">
    123.45
   </i18n:number>
4) for number and date/time: introduced the attributes 'locale'
   and 'src-locale', e.g.:
   <i18n:date src-pattern="short" src-locale="en_US" locale="de_DE">
    12/24/01
   </i18n:date>
   will result in 24.12.2001
   A given "real" pattern and src-pattern (not short, medium, long,
full)
   overwrites the locale and src-locale

I send a diff -u <old> <new> where <new> is:
a) -> src/org/apache/cocoon/transformation/I18nTransformer.java
b) -> xdocs/i18n-transformer.xml

Does anybody have suggestions/remarks?

Best regards,
Michael

--- I18nTransformer.java.orig   Tue Aug  7 12:36:07 2001
+++ I18nTransformer.java        Tue Aug  7 14:34:11 2001
@@ -176,6 +176,27 @@
  * &lt;/map:match&gt;
  * </pre>
  *
+ * <p/>
+ * <ul>
+ *  <li><strong><i18n:date/></strong> gives now only the date.</li>
+ *  <li><strong><i18n:date-time/></strong> gives the date and time.</li>
+ *  <li><strong><i18n:time/></strong> gives the time.</li>
+ *  <li>For date, date-time and time the pattern and src-pattern attribute 
+ *      may have also values of: "short", "medium",
+ *      "long" or "full".</li>
+ * </ul>
+ * <p/>
+ * <ul>
+ * <li>for date, date-time, time and number a different locale and
+ *     source-locale can be specified:
+ *     <i18n:date src-pattern="short" src-locale="en_US" locale="de_DE">
+ *      12/24/01
+ *     </i18n:date>
+ *     will result in 24.12.2001</li>
+ * <li>A given real pattern and src-pattern (not short, medium, long, full)
+ *     overwrites the locale and src-locale</li>
+ * </ul>
+ * <p/>
  * Future work coming:
  *
  * <ul>
@@ -186,6 +207,7 @@
  * @author <a href="mailto:[EMAIL PROTECTED]";>Marcus Crafter</a>
  * @author <a href="mailto:[EMAIL PROTECTED]";>Konstantin Piroumian</a>
  * @author <a href="mailto:[EMAIL PROTECTED]";>Lassi Immonen</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]";>Michael Enke</a>
  */
 public class I18nTransformer extends AbstractTransformer
     implements Composable, Poolable, Configurable {
@@ -193,10 +215,10 @@
     protected ComponentManager manager;
 
     /**
-     * The namespace for i18n is "http://apache.org/cocoon/i18n/2.0";
+     * The namespace for i18n is "http://apache.org/cocoon/i18n/2.1";
      */
     public static final String I18N_NAMESPACE_URI =
-        "http://apache.org/cocoon/i18n/2.0";;
+        "http://apache.org/cocoon/i18n/2.1";;
 
     //
     // Dictionary elements and attributes
@@ -216,12 +238,16 @@
     public static final String I18N_TRANSLATE_ELEMENT = "translate";
     public static final String I18N_PARAM_ELEMENT = "param";
     public static final String I18N_DATE_ELEMENT = "date";
+    public static final String I18N_DATE_TIME_ELEMENT = "date-time";
+    public static final String I18N_TIME_ELEMENT = "time";
     public static final String I18N_NUMBER_ELEMENT = "number";
 
     // number and date formatting attributes
     public static final String I18N_SRC_PATTERN_ATTRIBUTE = "src-pattern";
     public static final String I18N_PATTERN_ATTRIBUTE = "pattern";
     public static final String I18N_VALUE_ATTRIBUTE = "value";
+    public static final String I18N_LOCALE_ATTRIBUTE = "locale";
+    public static final String I18N_SRC_LOCALE_ATTRIBUTE = "src-locale";
 
     // configuration parameters
     public static final String I18N_CATALOGUE_NAME = "catalogue-name";
@@ -253,7 +279,9 @@
     private static final int STATE_TRANSLATE_KEY = 5;
     private static final int STATE_TRANSLATE_TEXT_KEY = 6;
     private static final int STATE_INSIDE_DATE = 7;
-    private static final int STATE_INSIDE_NUMBER = 8;
+    private static final int STATE_INSIDE_DATE_TIME = 8;
+    private static final int STATE_INSIDE_TIME = 9;
+    private static final int STATE_INSIDE_NUMBER = 10;
 
     /**
      * Current state of the transformer.
@@ -316,7 +344,7 @@
     /**
      * Locale setting.
      */
-    private Locale locale;
+    private Locale locale, loc, srcLoc;
 
     /**
      * Date element attributes and their values.
@@ -534,6 +562,24 @@
 
                 setFormattingParams(attr);
                 current_state = STATE_INSIDE_DATE;
+            } else if (I18N_DATE_TIME_ELEMENT.equals(name)) {
+                if (current_state != STATE_OUTSIDE) {
+                    throw new SAXException(this.getClass().getName()
+                                           + ": i18n:date-time elements are not 
+allowed "
+                                           + "inside of other i18n elements.");
+                }
+
+                setFormattingParams(attr);
+                current_state = STATE_INSIDE_DATE_TIME;
+            } else if (I18N_TIME_ELEMENT.equals(name)) {
+                if (current_state != STATE_OUTSIDE) {
+                    throw new SAXException(this.getClass().getName()
+                                           + ": i18n:date elements are not allowed "
+                                           + "inside of other i18n elements.");
+                }
+
+                setFormattingParams(attr);
+                current_state = STATE_INSIDE_TIME;
             } else if (I18N_NUMBER_ELEMENT.equals(name)) {
                 if (current_state != STATE_OUTSIDE) {
                     throw new SAXException(this.getClass().getName()
@@ -573,6 +619,16 @@
             formattingParams.put(I18N_VALUE_ATTRIBUTE, attr_value);
         }
 
+        attr_value = attr.getValue(I18N_LOCALE_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_LOCALE_ATTRIBUTE, attr_value);
+        }
+
+        attr_value = attr.getValue(I18N_SRC_LOCALE_ATTRIBUTE);
+        if (attr_value != null) {
+            formattingParams.put(I18N_SRC_LOCALE_ATTRIBUTE, attr_value);
+        }
+
         attr_value = attr.getValue(I18N_TYPE_ATTRIBUTE);
         if (attr_value != null) {
             formattingParams.put(I18N_TYPE_ATTRIBUTE, attr_value);
@@ -605,8 +661,10 @@
                     break;
                 }
             case STATE_INSIDE_DATE:
+            case STATE_INSIDE_DATE_TIME:
+            case STATE_INSIDE_TIME:
                 {
-                    endDateElement();
+                    endDate_TimeElement();
                     break;
                 }
             case STATE_INSIDE_NUMBER:
@@ -688,6 +746,9 @@
                 break;
             }
         case STATE_INSIDE_DATE:
+        case STATE_INSIDE_DATE_TIME:
+        case STATE_INSIDE_TIME:
+        case STATE_INSIDE_NUMBER:
             {
                 if (formattingParams != null) {
                     if (formattingParams.get(I18N_VALUE_ATTRIBUTE) == null) {
@@ -699,18 +760,6 @@
                 }
                 break;
             }
-        case STATE_INSIDE_NUMBER:
-            {
-                if (formattingParams != null) {
-                    if (formattingParams.get(I18N_PATTERN_ATTRIBUTE) == null) {
-                        formattingParams.put(I18N_PATTERN_ATTRIBUTE, key);
-                    } else {
-                        // how to use the text inside of number element?
-                    }
-
-                }
-                break;
-            }
         default:
             {
                 throw new SAXException(this.getClass().getName()
@@ -812,9 +861,11 @@
                     debug("Put param value: " + param_value);
                     formattingParams.put(I18N_VALUE_ATTRIBUTE, param_value);
                 }
-                if ("date".equals(paramType)) {
-                    debug("Formatting date param: " + formattingParams);
-                    param_value = formatDate(formattingParams);
+                if ("date".equals(paramType) ||
+                   "date-time".equals(paramType) ||
+                   "time".equals(paramType)) {
+                    debug("Formatting date_time param: " + formattingParams);
+                    param_value = formatDate_Time(formattingParams);
                 } else if ("number".equals(paramType)) {
                     debug("Formatting number param: " + formattingParams);
                     param_value = formatNumber(formattingParams);
@@ -848,17 +899,43 @@
         current_state = STATE_OUTSIDE;
     }
 
-    private void endDateElement() throws SAXException {
-        String result = formatDate(formattingParams);
+    private void endDate_TimeElement() throws SAXException {
+        String result = formatDate_Time(formattingParams);
         super.contentHandler.characters(result.toCharArray(), 0, result.length());
         current_state = STATE_OUTSIDE;
     }
 
-    private String formatDate(Map params) throws SAXException {
+    private Locale getLocale(Map params, String attribute) {
+       Locale locale = this.locale;
+        // the specific locale value
+        String lc = (String)params.get(attribute);
+       if(lc != null) try {
+           
+            String[] matches = new RE("_").split(lc);
+            String l = matches.length > 0
+                       ? matches[0] : Locale.getDefault().getLanguage();
+            String c = matches.length > 1 ? matches[1] : "";
+            String v = matches.length > 2 ? matches[2] : "";
+            locale = new Locale(l, c, v);
+       }
+       catch(Exception e) {}
+       return locale;
+    }
+       
+    private String formatDate_Time(Map params) throws SAXException {
+        SimpleDateFormat to_fmt = null, from_fmt;
+       String element = null;
+       int srcStyle = DateFormat.SHORT, style = DateFormat.SHORT;
+       boolean realPattern = false, realSrcPattern = false;
+
         if (params == null) {
             throw new SAXException(this.getClass().getName()
-                                   + ": i18n:date - error in element attributes.");
+                                   + ": i18n:"+element+" - error in element 
+attributes.");
         }
+
+       loc = getLocale(params, I18N_LOCALE_ATTRIBUTE);
+       srcLoc = getLocale(params, I18N_SRC_LOCALE_ATTRIBUTE);
+
         // from pattern
         String srcPattern = (String)params.get(I18N_SRC_PATTERN_ATTRIBUTE);
         // to pattern
@@ -866,19 +943,70 @@
         // the date value
         String value = (String)params.get(I18N_VALUE_ATTRIBUTE);
 
+       if(srcPattern == null) {
+           srcStyle = DateFormat.DEFAULT;
+       }
+       else {
+           if(srcPattern.equalsIgnoreCase("short"))
+               srcStyle = DateFormat.SHORT;
+           else if(srcPattern.equalsIgnoreCase("medium"))
+               srcStyle = DateFormat.MEDIUM;
+           else if(srcPattern.equalsIgnoreCase("long"))
+               srcStyle = DateFormat.LONG;
+           else if(srcPattern.equalsIgnoreCase("full"))
+               srcStyle = DateFormat.FULL;
+           /* really a src-pattern */
+           else
+               realSrcPattern = true;
+       }
+       if(pattern == null) {
+           style = DateFormat.DEFAULT;
+       }
+       else {
+           if(pattern.equalsIgnoreCase("short"))
+               style = DateFormat.SHORT;
+           else if(pattern.equalsIgnoreCase("medium"))
+               style = DateFormat.MEDIUM;
+           else if(pattern.equalsIgnoreCase("long"))
+               style = DateFormat.LONG;
+           else if(pattern.equalsIgnoreCase("full"))
+               style = DateFormat.FULL;
+           /* really a pattern */
+           else
+               realPattern = true;
+       }
+
+       if (current_state == STATE_INSIDE_DATE) {
+           element = I18N_DATE_ELEMENT;
+           to_fmt = (SimpleDateFormat)DateFormat.
+               getDateInstance(style, loc);
+           from_fmt = (SimpleDateFormat)DateFormat.
+               getDateInstance(srcStyle, srcLoc);
+       }
+       else if (current_state == STATE_INSIDE_DATE_TIME) {
+           element = I18N_DATE_TIME_ELEMENT;
+           to_fmt = (SimpleDateFormat)DateFormat.
+               getDateTimeInstance(style, style, loc);
+           from_fmt = (SimpleDateFormat)DateFormat.
+               getDateTimeInstance(srcStyle, srcStyle, srcLoc);
+       }
+       else { /* STATE_INSIDE_TIME */
+           element = I18N_TIME_ELEMENT;
+           to_fmt = (SimpleDateFormat)DateFormat.
+               getTimeInstance(style, loc);
+           from_fmt = (SimpleDateFormat)DateFormat.
+               getTimeInstance(srcStyle, srcLoc);
+       }
+
         // parsed date object
         Date dateValue = null;
 
-        // src format
-        SimpleDateFormat from_fmt = (SimpleDateFormat)DateFormat.getInstance();
-        if (srcPattern != null) {
+       // pattern overwrites locale format
+        if (realSrcPattern) {
             from_fmt.applyPattern(srcPattern);
         }
 
-        // result pattern is localized
-        SimpleDateFormat to_fmt = (SimpleDateFormat)DateFormat.getDateTimeInstance(
-                                      DateFormat.DEFAULT, DateFormat.DEFAULT, locale);
-        if (pattern != null) {
+        if (realPattern) {
             to_fmt.applyPattern(pattern);
         }
 
@@ -896,7 +1024,7 @@
 
         // we have all necessary data here: do formatting.
         String result = to_fmt.format(dateValue);
-        debug("i18n:date result: " + result);
+        debug("i18n:"+element+" result: " + result);
         return result;
     }
 
@@ -923,26 +1051,33 @@
         // parsed number
         Number numberValue = null;
 
+       // locale, may be switched locale
+       loc = getLocale(params, I18N_LOCALE_ATTRIBUTE);
+       srcLoc = getLocale(params, I18N_SRC_LOCALE_ATTRIBUTE);
+
+
         // src format
-        DecimalFormat from_fmt = (DecimalFormat)NumberFormat.getInstance();
+        DecimalFormat from_fmt = (DecimalFormat)NumberFormat.getInstance(srcLoc);
+       // src-pattern overwrites locale format
         if (srcPattern != null) {
             from_fmt.applyPattern(srcPattern);
         }
 
-        // result pattern is localized
+       // to format
         DecimalFormat to_fmt = null;
         if (subType == null) {
-            to_fmt = (DecimalFormat)NumberFormat.getInstance(locale);
+            to_fmt = (DecimalFormat)NumberFormat.getInstance(loc);
         } else if (subType.equals("currency")) {
-            to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(locale);
+            to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(loc);
         } else if (subType.equals("percent")) {
-            to_fmt = (DecimalFormat)NumberFormat.getPercentInstance(locale);
+            to_fmt = (DecimalFormat)NumberFormat.getPercentInstance(loc);
         }
+
+       // pattern overwrites locale format
         if (pattern != null) {
             to_fmt.applyPattern(pattern);
         }
 
-        // get current date and time by default
         if (value == null) {
             numberValue = new Long(0);
         } else {
--- i18n-transformer.xml.orig   Tue Aug  7 14:28:16 2001
+++ i18n-transformer.xml        Tue Aug  7 14:32:56 2001
@@ -28,11 +28,14 @@
                                                <code>I18nTransformer</code>
                                        </link>
                                , it uses XML dictionaries for all the i18n data. The 
namespace of i18n is defined as follows:
-                               
<code>xmlns:i18n="http://apache.org/cocoon/i18n/2.0";</code>
+                               
+<code>xmlns:i18n="http://apache.org/cocoon/i18n/2.1";</code>
                                </p>
                                <p>
                                First implementation was developed by <link 
href="mailto:[EMAIL PROTECTED]";>Lassi Immonen</link>. In this implementation 
syntax was changed according to the <link 
href="http://www.infozone-group.org";>Infozone Group's</link> i18n proposal (with a 
little difference) and some new features were implemented.
                                </p>
+                               <p>
+                               Enhancements for number, date and time have been 
+contributed by <link href="mailto:[EMAIL PROTECTED]";>Michael 
+Enke</link>.
+                               </p>
                        <ul>
                                <li>Name : i18n</li>
                                <li>Class: 
org.apache.cocoon.transformation.I18nTransformer</li>
@@ -168,10 +171,19 @@
                                </p>
                        </s2>
                        <s2 title="Date, time and number formatting">
-                               <p>To format dates and time according to the current 
locale use <code><![CDATA[<i18n:date src-pattern="dd/MM/yyyy" pattern="dd:MMM:yyyy" 
value="01/01/2001" />]]></code>. The <code>'src-pattern'</code> attribute will be used 
to parse the <code>'value'</code>, then the date will be formatted according to the 
current locale using the format specified by <code>'pattern'</code> attribute.
+                               <p>To format dates according to the current locale use 
+<code><![CDATA[<i18n:date src-pattern="dd/MM/yyyy" pattern="dd:MMM:yyyy" 
+value="01/01/2001" />]]></code>. The <code>'src-pattern'</code> attribute will be 
+used to parse the <code>'value'</code>, then the date will be formatted according to 
+the current locale using the format specified by <code>'pattern'</code> attribute.
+                               </p>
+                               <p>To format time for a locale (e.g. de_DE) use 
+<code><![CDATA[<i18n:time src-pattern="dd/MM/yyyy" locale="de_DE" value="01/01/2001" 
+/>]]></code>. The <code>'src-pattern'</code> and <code>'pattern'</code> attribute may 
+also contain <code>'short'</code>, <code>'medium'</code>, <code>'long'</code> or 
+<code>'full'</code>. The date will be formatted according to this format.
+                               </p>
+                               <p>To format date and time use 
+<code><![CDATA[<i18n:date-time />]]></code>.
+                               </p>
+                               <p>It is also possible to specify a src-locale:  
+<code><![CDATA[<i18n:date src-pattern="short" src-locale="en_US" locale="de_DE"> 
+12/24/01 </i18n:date> ]]></code> will result in 24.12.2001
+                               </p>
+                               <p>
+                               A given real <code>pattern</code> and 
+<code>src-pattern</code> (not short, medium, long, full) overwrites the 
+<code>locale</code> and <code>src-locale</code>.
                                </p>
                                <p>
-                                       If no pattern was specified then the date will 
be formatted with the <code>DateFormat.DEFAULT</code> format (both date and time). If 
no value for the date is specified then the current date will be used. E.g.: 
<code><![CDATA[<i18n:date ]]></code> will result in the current date and time, 
formatted with default localized pattern.
+                                       If no pattern was specified then the date will 
+be formatted with the <code>DateFormat.DEFAULT</code> format (both date and time). If 
+no value for the date is specified then the current date will be used. E.g.: 
+<code><![CDATA[<i18n:date/> ]]></code> will result in the current date, formatted 
+with default localized pattern.
                                </p>
                                <p>To format numbers in locale sensitive manner use 
<code><![CDATA[<i18n:number pattern="0.##" value="2.0" />]]></code>. This will be 
useful for Arabic, Indian, etc. number formatting. Additionally, currencies and 
percent formatting can be used. E.g.: 
                                </p>

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to