alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ExsltDatetime.java)

This example Java source code file (ExsltDatetime.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

calendar, common, eeee, empty_str, gmt, hh\:mm\:ss, mm\-dd, mmmm, parseexception, simpledateformat, string, stringbuffer, text, util

The ExsltDatetime.java Java example source code

/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * 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.
 */
/*
 * $Id: ExsltDatetime.java,v 1.2.4.1 2005/09/10 18:50:49 jeffsuttor Exp $
 */

package com.sun.org.apache.xalan.internal.lib;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import com.sun.org.apache.xpath.internal.objects.XBoolean;
import com.sun.org.apache.xpath.internal.objects.XNumber;
import com.sun.org.apache.xpath.internal.objects.XObject;

/**
 * This class contains EXSLT dates and times extension functions.
 * It is accessed by specifying a namespace URI as follows:
 * <pre>
 *    xmlns:datetime="http://exslt.org/dates-and-times"
 * </pre>
 *
 * The documentation for each function has been copied from the relevant
 * EXSLT Implementer page.
 *
 * @see <a href="http://www.exslt.org/">EXSLT
 * @xsl.usage general
 */

public class ExsltDatetime
{
    // Datetime formats (era and zone handled separately).
    static final String dt = "yyyy-MM-dd'T'HH:mm:ss";
    static final String d = "yyyy-MM-dd";
    static final String gym = "yyyy-MM";
    static final String gy = "yyyy";
    static final String gmd = "--MM-dd";
    static final String gm = "--MM--";
    static final String gd = "---dd";
    static final String t = "HH:mm:ss";
    static final String EMPTY_STR = "";

    /**
     * The date:date-time function returns the current date and time as a date/time string.
     * The date/time string that's returned must be a string in the format defined as the
     * lexical representation of xs:dateTime in
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime] of
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes] and
     * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601] for details.
     * The date/time string format must include a time zone, either a Z to indicate Coordinated
     * Universal Time or a + or - followed by the difference between the difference from UTC
     * represented as hh:mm.
     */
    public static String dateTime()
    {
      Calendar cal = Calendar.getInstance();
      Date datetime = cal.getTime();
      // Format for date and time.
      SimpleDateFormat dateFormat = new SimpleDateFormat(dt);

      StringBuffer buff = new StringBuffer(dateFormat.format(datetime));
      // Must also include offset from UTF.
      // Get the offset (in milliseconds).
      int offset = cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET);
      // If there is no offset, we have "Coordinated
      // Universal Time."
      if (offset == 0)
        buff.append("Z");
      else
      {
        // Convert milliseconds to hours and minutes
        int hrs = offset/(60*60*1000);
        // In a few cases, the time zone may be +/-hh:30.
        int min = offset%(60*60*1000);
        char posneg = hrs < 0? '-': '+';
        buff.append(posneg).append(formatDigits(hrs)).append(':').append(formatDigits(min));
      }
      return buff.toString();
    }

    /**
     * Represent the hours and minutes with two-digit strings.
     * @param q hrs or minutes.
     * @return two-digit String representation of hrs or minutes.
     */
    private static String formatDigits(int q)
    {
      String dd = String.valueOf(Math.abs(q));
      return dd.length() == 1 ? '0' + dd : dd;
    }

    /**
     * The date:date function returns the date specified in the date/time string given
     * as the argument. If no argument is given, then the current local date/time, as
     * returned by date:date-time is used as a default argument.
     * The date/time string that's returned must be a string in the format defined as the
     * lexical representation of xs:dateTime in
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime] of
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * If the argument is not in either of these formats, date:date returns an empty string ('').
     * The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes] and
     * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601] for details.
     * The date is returned as a string with a lexical representation as defined for xs:date in
     * [3.2.9 date] of [XML Schema Part 2: Datatypes]. The date format is basically CCYY-MM-DD,
     * although implementers should consult [XML Schema Part 2: Datatypes] and [ISO 8601] for details.
     * If no argument is given or the argument date/time specifies a time zone, then the date string
     * format must include a time zone, either a Z to indicate Coordinated Universal Time or a + or -
     * followed by the difference between the difference from UTC represented as hh:mm. If an argument
     * is specified and it does not specify a time zone, then the date string format must not include
     * a time zone.
     */
    public static String date(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String leader = edz[0];
      String datetime = edz[1];
      String zone = edz[2];
      if (datetime == null || zone == null)
        return EMPTY_STR;

      String[] formatsIn = {dt, d};
      String formatOut = d;
      Date date = testFormats(datetime, formatsIn);
      if (date == null) return EMPTY_STR;

      SimpleDateFormat dateFormat = new SimpleDateFormat(formatOut);
      dateFormat.setLenient(false);
      String dateOut = dateFormat.format(date);
      if (dateOut.length() == 0)
          return EMPTY_STR;
      else
        return (leader + dateOut + zone);
    }


    /**
     * See above.
     */
    public static String date()
    {
      String datetime = dateTime().toString();
      String date = datetime.substring(0, datetime.indexOf("T"));
      String zone = datetime.substring(getZoneStart(datetime));
      return (date + zone);
    }

    /**
     * The date:time function returns the time specified in the date/time string given
     * as the argument. If no argument is given, then the current local date/time, as
     * returned by date:date-time is used as a default argument.
     * The date/time string that's returned must be a string in the format defined as the
     * lexical representation of xs:dateTime in
     * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime">[3.2.7 dateTime] of
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * If the argument string is not in this format, date:time returns an empty string ('').
     * The date/time format is basically CCYY-MM-DDThh:mm:ss, although implementers should consult
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes] and
     * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601] for details.
     * The date is returned as a string with a lexical representation as defined for xs:time in
     * <a href="http://www.w3.org/TR/xmlschema-2/#time">[3.2.8 time] of [XML Schema Part 2: Datatypes].
     * The time format is basically hh:mm:ss, although implementers should consult [XML Schema Part 2:
     * Datatypes] and [ISO 8601] for details.
     * If no argument is given or the argument date/time specifies a time zone, then the time string
     * format must include a time zone, either a Z to indicate Coordinated Universal Time or a + or -
     * followed by the difference between the difference from UTC represented as hh:mm. If an argument
     * is specified and it does not specify a time zone, then the time string format must not include
     * a time zone.
     */
    public static String time(String timeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(timeIn);
      String time = edz[1];
      String zone = edz[2];
      if (time == null || zone == null)
        return EMPTY_STR;

      String[] formatsIn = {dt, d, t};
      String formatOut =  t;
      Date date = testFormats(time, formatsIn);
      if (date == null) return EMPTY_STR;
      SimpleDateFormat dateFormat = new SimpleDateFormat(formatOut);
      String out = dateFormat.format(date);
      return (out + zone);
    }

    /**
     * See above.
     */
    public static String time()
    {
      String datetime = dateTime().toString();
      String time = datetime.substring(datetime.indexOf("T")+1);

          // The datetime() function returns the zone on the datetime string.  If we
          // append it, we get the zone substring duplicated.
          // Fix for JIRA 2013

      // String zone = datetime.substring(getZoneStart(datetime));
      // return (time + zone);
      return (time);
    }

    /**
     * The date:year function returns the year of a date as a number. If no
     * argument is given, then the current local date/time, as returned by
     * date:date-time is used as a default argument.
     * The date/time string specified as the first argument must be a right-truncated
     * string in the format defined as the lexical representation of xs:dateTime in one
     * of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *   xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *   xs:date (CCYY-MM-DD)
     *   xs:gYearMonth (CCYY-MM)
     *   xs:gYear (CCYY)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double year(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      boolean ad = edz[0].length() == 0; // AD (Common Era -- empty leader)
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt, d, gym, gy};
      double yr = getNumber(datetime, formats, Calendar.YEAR);
      if (ad || yr == Double.NaN)
        return yr;
      else
        return -yr;
    }

    /**
     * See above.
     */
    public static double year()
    {
      Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.YEAR);
    }

    /**
     * The date:month-in-year function returns the month of a date as a number. If no argument
     * is given, then the current local date/time, as returned by date:date-time is used
     * as a default argument.
     * The date/time string specified as the first argument is a left or right-truncated
     * string in the format defined as the lexical representation of xs:dateTime in one of
     * the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *    xs:date (CCYY-MM-DD)
     *    xs:gYearMonth (CCYY-MM)
     *    xs:gMonth (--MM--)
     *    xs:gMonthDay (--MM-DD)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double monthInYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt, d, gym, gm, gmd};
      return getNumber(datetime, formats, Calendar.MONTH) + 1;
    }

    /**
     * See above.
     */
    public static double monthInYear()
    {
      Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.MONTH) + 1;
   }

    /**
     * The date:week-in-year function returns the week of the year as a number. If no argument
     * is given, then the current local date/time, as returned by date:date-time is used as the
     * default argument. For the purposes of numbering, counting follows ISO 8601: week 1 in a year
     * is the week containing the first Thursday of the year, with new weeks beginning on a Monday.
     * The date/time string specified as the argument is a right-truncated string in the format
     * defined as the lexical representation of xs:dateTime in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]. The
     * permitted formats are as follows:
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *    xs:date (CCYY-MM-DD)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double weekInYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt, d};
      return getNumber(datetime, formats, Calendar.WEEK_OF_YEAR);
    }

    /**
     * See above.
     */
    public static double weekInYear()
    {
       Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.WEEK_OF_YEAR);
   }

    /**
     * The date:day-in-year function returns the day of a date in a year
     * as a number. If no argument is given, then the current local
     * date/time, as returned by date:date-time is used the default argument.
     * The date/time string specified as the argument is a right-truncated
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *     xs:date (CCYY-MM-DD)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double dayInYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt, d};
      return getNumber(datetime, formats, Calendar.DAY_OF_YEAR);
    }

    /**
     * See above.
     */
    public static double dayInYear()
    {
       Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.DAY_OF_YEAR);
   }


    /**
     * The date:day-in-month function returns the day of a date as a number.
     * If no argument is given, then the current local date/time, as returned
     * by date:date-time is used the default argument.
     * The date/time string specified as the argument is a left or right-truncated
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *      xs:date (CCYY-MM-DD)
     *      xs:gMonthDay (--MM-DD)
     *      xs:gDay (---DD)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double dayInMonth(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      String[] formats = {dt, d, gmd, gd};
      double day = getNumber(datetime, formats, Calendar.DAY_OF_MONTH);
      return day;
    }

    /**
     * See above.
     */
    public static double dayInMonth()
    {
      Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.DAY_OF_MONTH);
   }

    /**
     * The date:day-of-week-in-month function returns the day-of-the-week
     * in a month of a date as a number (e.g. 3 for the 3rd Tuesday in May).
     * If no argument is given, then the current local date/time, as returned
     * by date:date-time is used the default argument.
     * The date/time string specified as the argument is a right-truncated string
     * in the format defined as the lexical representation of xs:dateTime in one
     * of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *      xs:date (CCYY-MM-DD)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double dayOfWeekInMonth(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats =  {dt, d};
      return getNumber(datetime, formats, Calendar.DAY_OF_WEEK_IN_MONTH);
    }

    /**
     * See above.
     */
    public static double dayOfWeekInMonth()
    {
       Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.DAY_OF_WEEK_IN_MONTH);
   }


    /**
     * The date:day-in-week function returns the day of the week given in a
     * date as a number. If no argument is given, then the current local date/time,
     * as returned by date:date-time is used the default argument.
     * The date/time string specified as the argument is a right-truncated string
     * in the format defined as the lexical representation of xs:dateTime in one
     * of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *      xs:date (CCYY-MM-DD)
     * If the date/time string is not in one of these formats, then NaN is returned.
                            The numbering of days of the week starts at 1 for Sunday, 2 for Monday and so on up to 7 for Saturday.
     */
    public static double dayInWeek(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt, d};
      return getNumber(datetime, formats, Calendar.DAY_OF_WEEK);
    }

    /**
     * See above.
     */
    public static double dayInWeek()
    {
       Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.DAY_OF_WEEK);
   }

    /**
     * The date:hour-in-day function returns the hour of the day as a number.
     * If no argument is given, then the current local date/time, as returned
     * by date:date-time is used the default argument.
     * The date/time string specified as the argument is a right-truncated
     * string  in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *     xs:time (hh:mm:ss)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double hourInDay(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt, t};
      return getNumber(datetime, formats, Calendar.HOUR_OF_DAY);
    }

    /**
     * See above.
     */
    public static double hourInDay()
    {
       Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.HOUR_OF_DAY);
   }

    /**
     * The date:minute-in-hour function returns the minute of the hour
     * as a number. If no argument is given, then the current local
     * date/time, as returned by date:date-time is used the default argument.
     * The date/time string specified as the argument is a right-truncated
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *      xs:time (hh:mm:ss)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double minuteInHour(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt,t};
      return getNumber(datetime, formats, Calendar.MINUTE);
    }

    /**
     * See above.
     */
   public static double minuteInHour()
    {
       Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.MINUTE);
   }

    /**
     * The date:second-in-minute function returns the second of the minute
     * as a number. If no argument is given, then the current local
     * date/time, as returned by date:date-time is used the default argument.
     * The date/time string specified as the argument is a right-truncated
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *      xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *      xs:time (hh:mm:ss)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static double secondInMinute(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return Double.NaN;

      String[] formats = {dt, t};
      return getNumber(datetime, formats, Calendar.SECOND);
    }

    /**
     * See above.
     */
    public static double secondInMinute()
    {
       Calendar cal = Calendar.getInstance();
      return cal.get(Calendar.SECOND);
    }

    /**
     * The date:leap-year function returns true if the year given in a date
     * is a leap year. If no argument is given, then the current local
     * date/time, as returned by date:date-time is used as a default argument.
     * The date/time string specified as the first argument must be a
     * right-truncated string in the format defined as the lexical representation
     * of xs:dateTime in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *    xs:date (CCYY-MM-DD)
     *    xs:gYearMonth (CCYY-MM)
     *    xs:gYear (CCYY)
     * If the date/time string is not in one of these formats, then NaN is returned.
     */
    public static XObject leapYear(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return new XNumber(Double.NaN);

      String[] formats = {dt, d, gym, gy};
      double dbl = getNumber(datetime, formats, Calendar.YEAR);
      if (dbl == Double.NaN)
        return new XNumber(Double.NaN);
      int yr = (int)dbl;
      return new XBoolean(yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0));
    }

    /**
     * See above.
     */
    public static boolean leapYear()
    {
      Calendar cal = Calendar.getInstance();
      int yr = (int)cal.get(Calendar.YEAR);
      return (yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0));
    }

    /**
     * The date:month-name function returns the full name of the month of a date.
     * If no argument is given, then the current local date/time, as returned by
     * date:date-time is used the default argument.
     * The date/time string specified as the argument is a left or right-truncated
     * string in the format defined as the lexical representation of xs:dateTime in
     *  one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *    xs:date (CCYY-MM-DD)
     *    xs:gYearMonth (CCYY-MM)
     *    xs:gMonth (--MM--)
     * If the date/time string is not in one of these formats, then an empty string ('')
     * is returned.
     * The result is an English month name: one of 'January', 'February', 'March',
     * 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November'
     * or 'December'.
     */
    public static String monthName(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return EMPTY_STR;

      String[] formatsIn = {dt, d, gym, gm};
      String formatOut = "MMMM";
      return getNameOrAbbrev(datetimeIn, formatsIn, formatOut);
    }

    /**
     * See above.
     */
    public static String monthName()
    {
      Calendar cal = Calendar.getInstance();
      String format = "MMMM";
      return getNameOrAbbrev(format);
    }

    /**
     * The date:month-abbreviation function returns the abbreviation of the month of
     * a date. If no argument is given, then the current local date/time, as returned
     * by date:date-time is used the default argument.
     * The date/time string specified as the argument is a left or right-truncated
     * string in the format defined as the lexical representation of xs:dateTime in
     * one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *    xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *    xs:date (CCYY-MM-DD)
     *    xs:gYearMonth (CCYY-MM)
     *    xs:gMonth (--MM--)
     * If the date/time string is not in one of these formats, then an empty string ('')
     * is returned.
     * The result is a three-letter English month abbreviation: one of 'Jan', 'Feb', 'Mar',
     * 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov' or 'Dec'.
     * An implementation of this extension function in the EXSLT date namespace must conform
     * to the behaviour described in this document.
     */
    public static String monthAbbreviation(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return EMPTY_STR;

      String[] formatsIn = {dt, d, gym, gm};
      String formatOut = "MMM";
      return getNameOrAbbrev(datetimeIn, formatsIn, formatOut);
    }

    /**
     * See above.
     */
    public static String monthAbbreviation()
    {
      String format = "MMM";
      return getNameOrAbbrev(format);
    }

    /**
     * The date:day-name function returns the full name of the day of the week
     * of a date.  If no argument is given, then the current local date/time,
     * as returned by date:date-time is used the default argument.
     * The date/time string specified as the argument is a left or right-truncated
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *     xs:date (CCYY-MM-DD)
     * If the date/time string is not in one of these formats, then the empty string ('')
     * is returned.
     * The result is an English day name: one of 'Sunday', 'Monday', 'Tuesday', 'Wednesday',
     * 'Thursday' or 'Friday'.
     * An implementation of this extension function in the EXSLT date namespace must conform
     * to the behaviour described in this document.
     */
    public static String dayName(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return EMPTY_STR;

      String[] formatsIn = {dt, d};
      String formatOut = "EEEE";
      return getNameOrAbbrev(datetimeIn, formatsIn, formatOut);
    }

    /**
     * See above.
     */
    public static String dayName()
    {
      String format = "EEEE";
      return getNameOrAbbrev(format);
    }

    /**
     * The date:day-abbreviation function returns the abbreviation of the day
     * of the week of a date. If no argument is given, then the current local
     * date/time, as returned  by date:date-time is used the default argument.
     * The date/time string specified as the argument is a left or right-truncated
     * string in the format defined as the lexical representation of xs:dateTime
     * in one of the formats defined in
     * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes].
     * The permitted formats are as follows:
     *     xs:dateTime (CCYY-MM-DDThh:mm:ss)
     *     xs:date (CCYY-MM-DD)
     * If the date/time string is not in one of these formats, then the empty string
     * ('') is returned.
     * The result is a three-letter English day abbreviation: one of 'Sun', 'Mon', 'Tue',
     * 'Wed', 'Thu' or 'Fri'.
     * An implementation of this extension function in the EXSLT date namespace must conform
     * to the behaviour described in this document.
     */
    public static String dayAbbreviation(String datetimeIn)
      throws ParseException
    {
      String[] edz = getEraDatetimeZone(datetimeIn);
      String datetime = edz[1];
      if (datetime == null)
        return EMPTY_STR;

      String[] formatsIn = {dt, d};
      String formatOut = "EEE";
      return getNameOrAbbrev(datetimeIn, formatsIn, formatOut);
    }

    /**
     * See above.
     */
    public static String dayAbbreviation()
    {
      String format = "EEE";
      return getNameOrAbbrev(format);
    }

    /**
     * Returns an array with the 3 components that a datetime input string
     * may contain: - (for BC era), datetime, and zone. If the zone is not
     * valid, return null for that component.
     */
    private static String[] getEraDatetimeZone(String in)
    {
      String leader = "";
      String datetime = in;
      String zone = "";
      if (in.charAt(0)=='-' && !in.startsWith("--"))
      {
        leader = "-"; //  '+' is implicit , not allowed
        datetime = in.substring(1);
      }
      int z = getZoneStart(datetime);
      if (z > 0)
      {
        zone = datetime.substring(z);
        datetime = datetime.substring(0, z);
      }
      else if (z == -2)
        zone = null;
      //System.out.println("'" + leader + "' " + datetime + " " + zone);
      return new String[]{leader, datetime, zone};
    }

    /**
     * Get the start of zone information if the input ends
     * with 'Z' or +/-hh:mm. If a zone string is not
     * found, return -1; if the zone string is invalid,
     * return -2.
     */
    private static int getZoneStart (String datetime)
    {
      if (datetime.indexOf("Z") == datetime.length()-1)
        return datetime.length()-1;
      else if (datetime.length() >=6
                && datetime.charAt(datetime.length()-3) == ':'
                && (datetime.charAt(datetime.length()-6) == '+'
                    || datetime.charAt(datetime.length()-6) == '-'))
      {
        try
        {
          SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
          dateFormat.setLenient(false);
          Date d = dateFormat.parse(datetime.substring(datetime.length() -5));
          return datetime.length()-6;
        }
        catch (ParseException pe)
        {
          System.out.println("ParseException " + pe.getErrorOffset());
          return -2; // Invalid.
        }

      }
        return -1; // No zone information.
    }

    /**
     * Attempt to parse an input string with the allowed formats, returning
     * null if none of the formats work.
     */
    private static Date testFormats (String in, String[] formats)
      throws ParseException
    {
      for (int i = 0; i <formats.length; i++)
      {
        try
        {
          SimpleDateFormat dateFormat = new SimpleDateFormat(formats[i]);
          dateFormat.setLenient(false);
          return dateFormat.parse(in);
        }
        catch (ParseException pe)
        {
        }
      }
      return null;
    }


    /**
     * Parse the input string and return the corresponding calendar field
     * number.
     */
    private static double getNumber(String in, String[] formats, int calField)
      throws ParseException
    {
      Calendar cal = Calendar.getInstance();
      cal.setLenient(false);
      // Try the allowed formats, from longest to shortest.
      Date date = testFormats(in, formats);
      if (date == null) return Double.NaN;
      cal.setTime(date);
      return cal.get(calField);
    }

    /**
     *  Get the full name or abbreviation of the month or day.
     */
    private static String getNameOrAbbrev(String in,
                                         String[] formatsIn,
                                         String formatOut)
      throws ParseException
    {
      for (int i = 0; i <formatsIn.length; i++) // from longest to shortest.
      {
        try
        {
          SimpleDateFormat dateFormat = new SimpleDateFormat(formatsIn[i], Locale.ENGLISH);
          dateFormat.setLenient(false);
          Date dt = dateFormat.parse(in);
          dateFormat.applyPattern(formatOut);
          return dateFormat.format(dt);
        }
        catch (ParseException pe)
        {
        }
      }
      return "";
    }
    /**
     * Get the full name or abbreviation for the current month or day
     * (no input string).
     */
    private static String getNameOrAbbrev(String format)
    {
      Calendar cal = Calendar.getInstance();
      SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.ENGLISH);
      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].
     * 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.
     *
     * The author is 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();
    }

}

Other Java examples (source code examples)

Here is a short list of links related to this Java ExsltDatetime.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.