You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by mk...@apache.org on 2003/04/07 18:32:27 UTC

cvs commit: xml-xalan/java/src/org/apache/xalan/lib ExsltDatetime.java

mkwan       2003/04/07 09:32:26

  Modified:    java/src/org/apache/xalan/lib ExsltDatetime.java
  Log:
  Commit an implementation of the date-time:format-date() extension function
  (bugzilla 18713) contributed by Helg Bredow (helg.bredow@kalido.com).
  
  Revision  Changes    Path
  1.10      +201 -0    xml-xalan/java/src/org/apache/xalan/lib/ExsltDatetime.java
  
  Index: ExsltDatetime.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/lib/ExsltDatetime.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- ExsltDatetime.java	1 Apr 2003 19:45:48 -0000	1.9
  +++ ExsltDatetime.java	7 Apr 2003 16:32:26 -0000	1.10
  @@ -62,6 +62,7 @@
   import java.text.SimpleDateFormat;
   import java.util.Calendar;
   import java.util.Date;
  +import java.util.TimeZone;
   
   import org.apache.xpath.objects.XBoolean;
   import org.apache.xpath.objects.XNumber;
  @@ -943,6 +944,206 @@
         Calendar cal = Calendar.getInstance();
         SimpleDateFormat dateFormat = new SimpleDateFormat(format);
         return dateFormat.format(cal.getTime());
  +    }
  +
  +    /**
  +     * The date:format-date function formats a date/time according to a pattern.
  +     * <p>
  +     * The first argument to date:format-date specifies the date/time to be 
  +     * formatted. It must be right or left-truncated date/time strings in one of 
  +     * the formats defined in 
  +     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. 
  +     * The permitted formats are as follows: 
  +     * <ul>
  +     * <li>xs:dateTime (CCYY-MM-DDThh:mm:ss) 
  +     * <li>xs:date (CCYY-MM-DD) 
  +     * <li>xs:time (hh:mm:ss) 
  +     * <li>xs:gYearMonth (CCYY-MM) 
  +     * <li>xs:gYear (CCYY) 
  +     * <li>xs:gMonthDay (--MM-DD) 
  +     * <li>xs:gMonth (--MM--) 
  +     * <li>xs:gDay (---DD)
  +     * </ul>
  +     * The second argument is a string that gives the format pattern used to 
  +     * format the date. The format pattern must be in the syntax specified by 
  +     * the JDK 1.1 SimpleDateFormat class. The format pattern string is 
  +     * interpreted as described for the JDK 1.1 SimpleDateFormat class. 
  +     * <p>
  +     * If the date/time format is right-truncated (i.e. in a format other than 
  +     * xs:time, or xs:dateTime) then any missing components are assumed to be as 
  +     * follows: if no month is specified, it is given a month of 01; if no day 
  +     * is specified, it is given a day of 01; if no time is specified, it is 
  +     * given a time of 00:00:00. 
  +     * <p>
  +     * If the date/time format is left-truncated (i.e. xs:time, xs:gMonthDay, 
  +     * xs:gMonth or xs:gDay) and the format pattern has a token that uses a 
  +     * component that is missing from the date/time format used, then that token 
  +     * is replaced with an empty string ('') within the result.
  +     * 
  +     * @author Helg Bredow (helg.bredow@kalido.com)
  +     */
  +    public static String formatDate(String dateTime, String pattern)
  +    {
  +        final String yearSymbols = "Gy";
  +        final String monthSymbols = "M";
  +        final String daySymbols = "dDEFwW";
  +        TimeZone timeZone;
  +        String zone;
  +
  +        // Get the timezone information if it was supplied and modify the 
  +        // dateTime so that SimpleDateFormat will understand it.
  +        if (dateTime.endsWith("Z") || dateTime.endsWith("z"))
  +        {
  +            timeZone = TimeZone.getTimeZone("GMT");
  +            dateTime = dateTime.substring(0, dateTime.length()-1) + "GMT";
  +            zone = "z";
  +        }
  +        else if ((dateTime.length() >= 6) 
  +                 && (dateTime.charAt(dateTime.length()-3) == ':') 
  +                 && ((dateTime.charAt(dateTime.length()-6) == '+') 
  +                    || (dateTime.charAt(dateTime.length()-6) == '-')))
  +        {
  +            String offset = dateTime.substring(dateTime.length()-6);
  +            
  +            if ("+00:00".equals(offset) || "-00:00".equals(offset))
  +            {
  +                timeZone = TimeZone.getTimeZone("GMT");
  +            }
  +            else
  +            {
  +                timeZone = TimeZone.getTimeZone("GMT" + offset);
  +            }
  +            zone = "z";
  +            // Need to adjust it since SimpleDateFormat requires GMT+hh:mm but
  +            // we have +hh:mm.
  +            dateTime = dateTime.substring(0, dateTime.length()-6) + "GMT" + offset;
  +        }
  +        else
  +        {
  +            // Assume local time.
  +            timeZone = TimeZone.getDefault();
  +            zone = "";
  +            // Leave off the timezone since SimpleDateFormat will assume local
  +            // time if time zone is not included.
  +        }
  +        String[] formats = {dt + zone, d, gym, gy};
  +        
  +        // Try the time format first. We need to do this to prevent 
  +        // SimpleDateFormat from interpreting a time as a year. i.e we just need
  +        // to check if it's a time before we check it's a year.
  +        try
  +        {
  +            SimpleDateFormat inFormat = new SimpleDateFormat(t + zone);
  +            inFormat.setLenient(false);
  +            Date d= inFormat.parse(dateTime);
  +            SimpleDateFormat outFormat = new SimpleDateFormat(strip
  +                (yearSymbols + monthSymbols + daySymbols, pattern));
  +            outFormat.setTimeZone(timeZone);
  +            return outFormat.format(d);
  +        }
  +        catch (ParseException pe)
  +        {
  +        }
  +        
  +        // Try the right truncated formats.
  +        for (int i = 0; i < formats.length; i++)
  +        {
  +            try
  +            {
  +                SimpleDateFormat inFormat = new SimpleDateFormat(formats[i]);
  +                inFormat.setLenient(false);
  +                Date d = inFormat.parse(dateTime);
  +                SimpleDateFormat outFormat = new SimpleDateFormat(pattern);
  +                outFormat.setTimeZone(timeZone);
  +                return outFormat.format(d);
  +            }
  +            catch (ParseException pe)
  +            {
  +            }
  +        }
  +        
  +        // Now try the left truncated ones. The Java format() function doesn't
  +        // return the correct strings in this case. We strip any pattern 
  +        // symbols that shouldn't be output so that they are not defaulted to 
  +        // inappropriate values in the output.
  +        try
  +        {
  +            SimpleDateFormat inFormat = new SimpleDateFormat(gmd);
  +            inFormat.setLenient(false);          
  +            Date d = inFormat.parse(dateTime);
  +            SimpleDateFormat outFormat = new SimpleDateFormat(strip(yearSymbols, pattern));
  +            outFormat.setTimeZone(timeZone);
  +            return outFormat.format(d);
  +        }
  +        catch (ParseException pe)
  +        {
  +        }
  +        try
  +        {
  +            SimpleDateFormat inFormat = new SimpleDateFormat(gm);
  +            inFormat.setLenient(false);
  +            Date d = inFormat.parse(dateTime);
  +            SimpleDateFormat outFormat = new SimpleDateFormat(strip(yearSymbols, pattern));
  +            outFormat.setTimeZone(timeZone);
  +            return outFormat.format(d);
  +        }
  +        catch (ParseException pe)
  +        {
  +        }
  +        try
  +        {
  +            SimpleDateFormat inFormat = new SimpleDateFormat(gd);
  +            inFormat.setLenient(false);
  +            Date d = inFormat.parse(dateTime);
  +            SimpleDateFormat outFormat = new SimpleDateFormat(strip(yearSymbols + monthSymbols, pattern));
  +            outFormat.setTimeZone(timeZone);
  +            return outFormat.format(d);
  +        }
  +        catch (ParseException pe)
  +        {
  +        }
  +        return EMPTY_STR;
  +    }
  +    
  +    /**
  +     * Strips occurrences of the given character from a date format pattern.
  +     * @param symbols list of symbols to strip.
  +     * @param pattern
  +     * @return
  +     */
  +    private static String strip(String symbols, String pattern)
  +    {
  +        int quoteSemaphore = 0;
  +        int i = 0;
  +        StringBuffer result = new StringBuffer(pattern.length());
  +
  +        while (i < pattern.length())
  +        {
  +            char ch = pattern.charAt(i);
  +            if (ch == '\'')
  +            {
  +                // Assume it's an openening quote so simply copy the quoted 
  +                // text to the result. There is nothing to strip here.
  +                int endQuote = pattern.indexOf('\'', i + 1);
  +                if (endQuote == -1)
  +                {
  +                    endQuote = pattern.length();
  +                }
  +                result.append(pattern.substring(i, endQuote));
  +                i = endQuote++;
  +            }
  +            else if (symbols.indexOf(ch) > -1)
  +            {
  +                // The char needs to be stripped.
  +                i++;
  +            }
  +            else
  +            {
  +                result.append(ch);
  +                i++;
  +            }
  +        }
  +        return result.toString();
       }
   
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org