| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 1999 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Xalan" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache", |
| * nor may "Apache" appear in their name, without prior written |
| * permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 1999, Lotus |
| * Development Corporation., http://www.lotus.com. For more |
| * information on the Apache Software Foundation, please see |
| * <http://www.apache.org/>. |
| */ |
| |
| package org.apache.xml.utils; |
| |
| |
| import java.text.DecimalFormat; |
| import java.text.ParseException; |
| import java.text.SimpleDateFormat; |
| import java.util.Calendar; |
| import java.util.Date; |
| import java.util.GregorianCalendar; |
| |
| import javax.xml.transform.TransformerException; |
| import org.apache.xml.dtm.XType; |
| |
| /** |
| * <meta name="usage" content="general"/> |
| * This class contains a duration object. |
| */ |
| |
| public class DateTimeObj |
| { |
| // Datetime formats (era and zone handled separately). |
| public static final String dt1 = "yyyy-MM-dd'T'HH:mm:ss.ss"; |
| public static final String dt2 = "yyyy-MM-dd'T'HH:mm:ss"; |
| public static final String d = "yyyy-MM-dd"; |
| public static final String gym = "yyyy-MM"; |
| public static final String gy = "yyyy"; |
| public static final String gmd = "MM-dd"; |
| public static final String gm = "MM"; |
| public static final String gd = "dd"; |
| public static final String t1 = "HH:mm:ss.ss"; |
| public static final String t2 = "HH:mm:ss"; |
| |
| private int m_year; |
| private int m_month; |
| private int m_day; |
| private int m_T; |
| private int m_hour; |
| private int m_minute; |
| private double m_second; |
| private String m_zone; |
| private Date m_date; |
| private String m_dateTime; |
| private int m_size; |
| private boolean m_signed = false; |
| |
| /** |
| * The duration string must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMnD, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public DateTimeObj(String dateTimeIn) throws TransformerException |
| { |
| this(dateTimeIn, new String[]{dt2}); |
| } |
| |
| public DateTimeObj(String dateTimeIn, String[] formatsIn) throws TransformerException |
| { |
| try { |
| |
| int i; |
| |
| m_size = dateTimeIn.length(); |
| // Remember our Time separator |
| m_T = (i = dateTimeIn.indexOf("T")) != -1 ? i : m_size ; |
| // boundary check?? |
| String[] edz = getEraDatetimeZone(dateTimeIn); |
| m_signed = edz[0].length() >0; |
| m_dateTime = edz[1]; |
| m_zone = edz[2]; |
| if (m_dateTime == null || m_zone == null) |
| return; |
| |
| m_date = testFormats(m_dateTime, formatsIn); |
| int index = dateTimeIn.indexOf('.'); |
| double dec = (index <0) ? 0 :Double.parseDouble(m_dateTime.substring(index)); |
| |
| SimpleDateFormat dateFormat = new SimpleDateFormat(dt1); |
| dateFormat.setLenient(false); |
| Calendar cal = Calendar.getInstance(); |
| cal.setTime(m_date); |
| m_year = cal.get(Calendar.YEAR); |
| m_month = cal.get(Calendar.MONTH) + 1; // Calendar returns months starting at 0... |
| m_day = cal.get(Calendar.DATE); |
| m_hour = cal.get(Calendar.HOUR); |
| m_minute = cal.get(Calendar.MINUTE); |
| m_second = (index <0) ? cal.get(Calendar.SECOND) |
| : cal.get(Calendar.SECOND) + Double.parseDouble(m_dateTime.substring(index)); |
| } |
| catch (Exception ex) |
| { |
| throw new TransformerException(ex); |
| } |
| |
| } |
| |
| public DateTimeObj(Date date, String formatOut) throws TransformerException |
| { |
| //m_zone = date.getTimezoneOffset(); |
| SimpleDateFormat dateFormat = new SimpleDateFormat(formatOut); |
| dateFormat.setLenient(false); |
| m_dateTime = dateFormat.format(date); |
| m_date = date; |
| |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(date); |
| |
| m_signed = (cal.get(Calendar.ERA) == GregorianCalendar.BC); |
| m_year = cal.get(Calendar.YEAR); |
| // String monthStr = m_dateTime.substring(5, 7); |
| // m_month = Integer.valueOf(monthStr).intValue(); |
| // String dayStr = m_dateTime.substring(8, 10); |
| // m_day = Integer.valueOf(dayStr).intValue(); |
| m_month = cal.get(Calendar.MONTH) + 1; |
| m_day = cal.get(Calendar.DATE); |
| m_hour = cal.get(Calendar.HOUR); |
| m_minute = cal.get(Calendar.MINUTE); |
| m_second = cal.get(Calendar.SECOND); |
| |
| // m_year = date.getYear(); |
| // m_month = date.getMonth(); |
| // m_day = date.getDay(); |
| // m_hour = date.getHours(); |
| // m_minute = date.getMinutes(); |
| // m_second = date.getSeconds(); |
| } |
| |
| /** Added by JJK to support Xerces' stopgap internal representation |
| * as delivered through DTMSequence. We should work with them to |
| * converge on a shared time/date/duration object compatable with |
| * the schema spec. |
| * |
| * %BUG% They return some bogus fields due to normalization |
| * side-effects (they use a pseudodate of 2000/1/15 or something |
| * like that). To fix that we need to check the schema-type |
| * and ignore those fields... |
| * |
| * %BUG% No idea what format I should be using for m_dateTime! |
| * */ |
| public DateTimeObj(int[] xercesdate,String typeLocalName) |
| { |
| try |
| { |
| m_year = Math.abs(xercesdate[0]); |
| m_month = xercesdate[1]; |
| m_day = xercesdate[2]; |
| m_hour = xercesdate[3]; |
| m_minute = xercesdate[4]; |
| m_second = xercesdate[5]+(xercesdate[6]/1000); |
| //m_zone = xercesdate[6]; // not sure how encoded |
| |
| m_signed = (xercesdate[0] < 0); |
| |
| /* Works, but gives slightly different results. Need to |
| * investigate... |
| int type = XType.getTypeFromLocalName(typeLocalName); |
| String format; |
| switch (type) |
| { |
| case XType.DATE: |
| format = d; |
| break; |
| case XType.TIME: |
| format = t1; |
| break; |
| default: |
| format = dt1; |
| } |
| Calendar cal = Calendar.getInstance(); |
| cal.set(m_year,(m_month-1),m_day,m_hour,m_minute,(int)m_second); |
| |
| m_date = cal.getTime(); |
| SimpleDateFormat dateFormat = new SimpleDateFormat(format); |
| dateFormat.setLenient(false); |
| m_dateTime = dateFormat.format(m_date); |
| */ |
| |
| // Don't particularly like constructing this string, |
| // but will do for now. Need to investigate why Date or |
| // Calendar don't work here... |
| |
| m_dateTime = formatYears(m_year) + "-" + formatDigits(m_month) + "-" + formatDigits(m_day); |
| // m_dateTime = m_year + "-" + m_month + "-" + m_day; |
| if (m_hour != 0 && m_minute != 0 && m_second != 0) |
| m_dateTime = m_dateTime + "T" + formatDigits(m_hour) + ":" + formatDigits(m_minute) + ":" + m_second; |
| String[] formatsIn = {dt2, d, t2}; |
| m_date = testFormats(m_dateTime, formatsIn); |
| |
| if (m_signed) |
| m_dateTime = "-" + m_dateTime; |
| |
| } |
| catch (Exception ex) |
| { |
| throw new WrappedRuntimeException(ex); |
| } |
| |
| |
| // This is wrong but I'm not sure what format I should be using! |
| //SimpleDateFormat dateFormat = new SimpleDateFormat(); |
| //dateFormat.setLenient(false); |
| //m_dateTime=dateFormat.format(m_date); |
| } |
| |
| /** |
| * Attempt to parse an input string with the allowed formats, returning |
| * null if none of the formats work. Input formats are passed in longest to shortest, |
| * so if any parse operation fails with a parse error in the string, can |
| * immediately return null. |
| */ |
| 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) |
| { |
| if ( i == formats.length -1) |
| throw pe; |
| } |
| |
| } |
| return null; |
| |
| } |
| |
| /** |
| * 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 String[] getEraDatetimeZone(String in) throws TransformerException |
| { |
| String leader = ""; |
| String datetime = in; |
| String zone = ""; |
| if (in.charAt(0)=='-') |
| { |
| 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}; |
| } |
| |
| /** |
| * 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 Date normalizeDate(Date date, String zone) |
| { |
| if (zone == null || zone.length()==0 || zone.equals("Z") || zone.equals("00:00") ) |
| return date; |
| else |
| { |
| int sign = 1; |
| if (zone.startsWith("-")) |
| { |
| sign = -1; |
| } |
| int index = zone.indexOf(":"); |
| int hr = sign * (Integer.parseInt(zone.substring(1, index))); |
| int min = sign * (Integer.parseInt(zone.substring(index+1))); |
| Calendar cal = Calendar.getInstance(); |
| cal.setTime(date); |
| cal.add(Calendar.HOUR, hr); |
| cal.add(Calendar.MINUTE, min); |
| return cal.getTime(); |
| } |
| } |
| |
| /** |
| * 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 int getZoneStart (String datetime) throws TransformerException |
| { |
| if (datetime.indexOf("Z") == datetime.length()-1) |
| return datetime.indexOf("Z"); |
| else if ( |
| (datetime.lastIndexOf("-") == datetime.length()-6 && |
| datetime.charAt(datetime.length()-3) == ':') |
| || |
| (datetime.indexOf("+") == 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) |
| { |
| throw new TransformerException(pe); |
| //return -2; // Invalid. |
| } |
| |
| } |
| return -1; // No zone information. |
| } |
| |
| /** |
| * See dateTime. |
| */ |
| public static DateTimeObj date() throws TransformerException |
| { |
| return currentDateTime(d); |
| } |
| |
| |
| /** |
| * 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]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * 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]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> 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 DateTimeObj date(String dateIn) throws TransformerException |
| { |
| DateTimeObj dt = new DateTimeObj (dateIn, new String[]{d}); |
| |
| return dt; |
| } |
| |
| |
| public static DateTimeObj date(Date dateIn) throws TransformerException |
| { |
| DateTimeObj dt = new DateTimeObj (dateIn, d); |
| |
| return dt; |
| } |
| |
| |
| /** |
| * The date:time function returns the time specified in the time string given |
| * as the argument. |
| * The time string that's returned must be a string in the format defined as the |
| * lexical representation of xs:time in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#time">[3.2.7 time]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * If the argument string is not in this format, date:time returns an empty string (''). |
| * The time format is basically hh:mm:ss, although implementers should consult |
| * If no argument is given or the argument time specifies a time zone, then the time string |
| * format must include a time zone, 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 DateTimeObj time() throws TransformerException |
| { |
| return currentDateTime(t1); |
| } |
| |
| |
| public static DateTimeObj time(String timeIn) throws TransformerException |
| { |
| DateTimeObj dt = new DateTimeObj (timeIn, new String[]{t1, t2}); |
| |
| return dt; |
| } |
| |
| |
| public static DateTimeObj time(Date timeIn) throws TransformerException |
| { |
| DateTimeObj dt = new DateTimeObj (timeIn, t1); |
| |
| return dt; |
| } |
| |
| |
| public static DateTimeObj gYearMonth(String dateIn) throws TransformerException |
| { |
| // Check on java g Date stuff... |
| DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gym}); |
| |
| return dt; |
| } |
| |
| |
| public static DateTimeObj gYear(String dateIn) throws TransformerException |
| { |
| // Check on java g Date stuff... |
| DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gy}); |
| |
| return dt; |
| } |
| |
| |
| public static DateTimeObj gMonth(String dateIn) throws TransformerException |
| { |
| // Check on java g Date stuff... |
| DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gm}); |
| |
| return dt; |
| } |
| |
| public static DateTimeObj gMonthDay(String dateIn) throws TransformerException |
| { |
| // Check on java g Date stuff... |
| DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gmd}); |
| |
| return dt; |
| } |
| |
| |
| public static DateTimeObj gDay(String dateIn) throws TransformerException |
| { |
| // Check on java g Date stuff... |
| DateTimeObj dt = new DateTimeObj (dateIn, new String[]{gd}); |
| |
| return dt; |
| } |
| |
| |
| /** |
| * 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]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * 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]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> 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 DateTimeObj currentDateTime(String pattern) throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| Date datetime = cal.getTime(); |
| DateTimeObj dt = new DateTimeObj(datetime, pattern); |
| |
| 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) |
| dt.setZone("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? '-': '+'; |
| dt.setZone(posneg + formatDigits(hrs) + ':' + formatDigits(min)); |
| } |
| return dt; |
| } |
| |
| |
| /** |
| * See above |
| */ |
| public static DateTimeObj dateTime() throws TransformerException |
| { |
| return dateTime(dt1); |
| } |
| |
| |
| /** |
| * The date:date-time function returns the date and time specified in the date/time |
| * string given as the 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]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * 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]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> 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 DateTimeObj dateTime(String dateTimeIn) |
| throws TransformerException |
| { |
| return new DateTimeObj(dateTimeIn); |
| } |
| |
| /** |
| * 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; |
| } |
| |
| /** |
| * 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 formatYears(int q) |
| { |
| String dd = String.valueOf(Math.abs(q)); |
| int len = dd.length(); |
| for (int i=len; i<4; i++) |
| dd = "0" + dd; |
| return dd; |
| } |
| |
| /** |
| * The duration function returns the duration specified in the duration |
| * string given as the argument.. |
| * The duration string that's returned must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMn, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public Duration getYMDuration(DateTimeObj dt) throws TransformerException |
| { |
| Duration du = null; |
| double secs = new Long((m_date.getTime() - dt.m_date.getTime())/1000).doubleValue(); |
| |
| String sign = secs <0 ? "-" : ""; |
| double days = Math.abs(((secs/60)/60)/24); |
| double months = days/31 + (days%31 <15.5 ? 0 : 1); |
| int monthDu = new Double(months%12).intValue(); |
| int yearDu = new Double(months/12).intValue(); |
| |
| return new Duration(sign + "P" + (yearDu != 0 ? (Integer.toString(yearDu) + "Y") : "") |
| + (monthDu != 0 ? (Integer.toString(monthDu) + "M") : "") ); |
| } |
| |
| /** |
| * The duration function returns the duration specified in the duration |
| * string given as the argument.. |
| * The duration string that's returned must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMn, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public Duration getDTDuration(DateTimeObj dt) throws TransformerException |
| { |
| Duration du = null; |
| double secs = new Long((m_date.getTime() - dt.m_date.getTime())/1000).doubleValue(); |
| |
| String sign = secs <0 ? "-" : ""; |
| secs = Math.abs(secs); |
| double secDu = secs%60; |
| int mins = (new Double(secs)).intValue()/60; |
| int mnDu = mins%60; |
| int hours = mins/60; |
| int hourDu = hours%24; |
| int dayDu = hours/24; |
| |
| return new Duration(sign + "P" + (dayDu != 0 ? (Integer.toString(dayDu) + "D") : "") |
| + ((hourDu != 0 || mnDu != 0 || secDu != 0) ? "T" : "") |
| + (hourDu != 0 ? (Integer.toString(hourDu) + "H") : "") |
| + (mnDu != 0 ? (Integer.toString(mnDu) + "M") : "") |
| + (secDu != 0 ? (Double.toString(secDu) + "S") : "") ); |
| } |
| |
| |
| /** |
| * The duration function returns the duration specified in the duration |
| * string given as the argument.. |
| * The duration string that's returned must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMnDTnHnMnS, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public boolean lessThan(DateTimeObj dt) |
| { |
| if (m_zone.equals(dt.m_zone)) |
| { |
| if( m_date.before(dt.m_date)) |
| /* |
| if ((m_year < dt.m_year || (m_year == 0 && dt.m_year == 0)) && |
| (m_month < dt.m_month || (m_month == 0 && dt.m_month == 0)) && |
| (m_day < dt.m_day || (m_day ==0 && dt.m_day == 0)) && |
| (m_hour < dt.m_hour || (m_hour == 0 && dt.m_hour == 0)) && |
| (m_minute < m_minute || (m_minute == 0 && m_minute == 0)) && |
| (m_second < dt.m_second || (m_second == 0 && dt.m_second == 0)) ) |
| */ |
| return true; |
| else |
| return false; |
| } |
| else |
| { |
| Date date1 = normalizeDate(m_date, m_zone); |
| Date date2 = normalizeDate(dt.m_date, dt.m_zone); |
| if (date1.before(date2)) |
| return true; |
| else |
| return false; |
| } |
| } |
| |
| /** |
| * The duration function returns the duration specified in the duration |
| * string given as the argument.. |
| * The duration string that's returned must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMnDTnHnMnS, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public boolean lessThanOrEqual(DateTimeObj dt) |
| { |
| return (lessThan(dt) || equals(dt)); |
| } |
| |
| /** |
| * The duration function returns the duration specified in the duration |
| * string given as the argument.. |
| * The duration string that's returned must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMnDTnHnMnS, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public boolean greaterThan(DateTimeObj dt) |
| { |
| return dt.lessThan(this); |
| } |
| |
| /** |
| * The duration function returns the duration specified in the duration |
| * string given as the argument.. |
| * The duration string that's returned must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMnDTnHnMnS, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public boolean greaterThanOrEqual(DateTimeObj dt) |
| { |
| return (greaterThan(dt) || equals(dt)); |
| } |
| |
| |
| |
| /** |
| * The duration function returns the duration specified in the duration |
| * string given as the argument.. |
| * The duration string that's returned must be a string in the format defined as the |
| * lexical representation of xs:duration in |
| * <a href="http://www.w3.org/TR/xmlschema-2/#duration">[3.2.6 duration]</a> of |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a>. |
| * The duration format is basically PnYnMnDTnHnMnS, although implementers should consult |
| * <a href="http://www.w3.org/TR/xmlschema-2/">[XML Schema Part 2: Datatypes]</a> and |
| * <a href="http://www.iso.ch/markete/8601.pdf">[ISO 8601]</a> for details. |
| */ |
| public boolean equals(DateTimeObj dt) |
| { |
| if (m_zone.equals(dt.m_zone)) |
| { |
| if (m_year == dt.m_year && |
| m_month == dt.m_month && |
| m_day == dt.m_day && |
| m_hour == dt.m_hour && |
| m_minute == dt.m_minute && |
| m_second == dt.m_second) |
| return true; |
| else |
| return false; |
| } |
| else |
| { |
| Date date1 = normalizeDate(m_date, m_zone); |
| Date date2 = normalizeDate(dt.m_date, dt.m_zone); |
| if (date1.before(date2) || date2.before(date1)) |
| return false; |
| else |
| return true; |
| } |
| } |
| |
| |
| public DateTimeObj addDays(double days) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| cal.add(Calendar.DATE, new Double(days).intValue()); |
| |
| DateTimeObj dateTime = date(cal.getTime()); |
| dateTime.setZone(m_zone); |
| return dateTime; |
| |
| } |
| |
| |
| |
| public DateTimeObj addYMDurationToDateTime(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? -1 : 1; |
| cal.add(Calendar.YEAR, sign * (d.getYears())); |
| cal.add(Calendar.MONTH, sign * (d.getMonths())); |
| |
| DateTimeObj dateTime = new DateTimeObj(cal.getTime(), dt2 ); |
| dateTime.setZone(m_zone); |
| return dateTime; |
| |
| } |
| |
| public DateTimeObj addYMDurationToDate(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? -1 : 1; |
| cal.add(Calendar.YEAR, sign * (d.getYears())); |
| cal.add(Calendar.MONTH, sign * (d.getMonths())); |
| DateTimeObj dt = date(cal.getTime()); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| public DateTimeObj subtractYMDurationFromDateTime(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? 1 : -1; |
| cal.add(Calendar.MONTH, sign * (d.getMonths() + (d.getYears() * 12))); |
| |
| DateTimeObj dateTime = new DateTimeObj(cal.getTime(), dt1); |
| dateTime.setZone(m_zone); |
| return dateTime; |
| |
| } |
| |
| public DateTimeObj subtractYMDurationFromDate(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? 1 : -1; |
| cal.add(Calendar.MONTH, sign * (d.getMonths() + (d.getYears() * 12))); |
| |
| DateTimeObj dt = date(cal.getTime()); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| |
| public DateTimeObj addDTDurationToDateTime(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? -1 : 1; |
| double secs = d.getSeconds() + (((((d.getDays() * 24) + d.getHours()) * 60) + d.getMinutes()) * 60); |
| int intVal = new Double(secs).intValue(); |
| cal.add(Calendar.SECOND , sign * intVal); |
| |
| Date date = cal.getTime(); |
| SimpleDateFormat dateFormat = new SimpleDateFormat(dt2); |
| dateFormat.setLenient(false); |
| String dateTime = dateFormat.format(date); |
| if (secs - intVal != 0) |
| { |
| String val = Double.toString(secs); |
| int index = val.indexOf('.'); |
| dateTime = (index<0) ? dateTime : dateTime + val.substring(index); |
| } |
| //DateTimeObj dt = new DateTimeObj(cal.getTime(), dt2); |
| DateTimeObj dt = new DateTimeObj(dateTime); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| |
| |
| public DateTimeObj addDTDurationToDate(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? -1 : 1; |
| cal.add(Calendar.MONTH, sign * (d.getMonths())); |
| cal.add(Calendar.DATE, sign * (d.getDays())); |
| |
| DateTimeObj dt = date(cal.getTime()); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| |
| public DateTimeObj addDTDurationToTime(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? -1 : 1; |
| double secs = d.getSeconds() + ((((d.getHours()) * 60) + d.getMinutes()) * 60); |
| int intVal = new Double(secs).intValue(); |
| cal.add(Calendar.SECOND , sign * intVal); |
| |
| Date date = cal.getTime(); |
| SimpleDateFormat dateFormat = new SimpleDateFormat(t2); |
| dateFormat.setLenient(false); |
| String dateTime = dateFormat.format(date); |
| if (secs - intVal != 0) |
| { |
| String val = Double.toString(secs); |
| int index = val.indexOf('.'); |
| dateTime = (index<0) ? dateTime : dateTime + val.substring(index); |
| } |
| DateTimeObj dt = time(dateTime); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| |
| public DateTimeObj subtractDTDurationFromDateTime(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? 1 : -1; |
| double secs = d.getSeconds() + (((((d.getDays() * 24) + d.getHours()) * 60) + d.getMinutes()) * 60); |
| cal.add(Calendar.SECOND , sign * (new Double (Math.floor(secs)).intValue())); |
| |
| DateTimeObj dt = new DateTimeObj(cal.getTime(), dt1); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| public DateTimeObj subtractDTDurationFromDate(Duration d) |
| throws TransformerException |
| { |
| |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? 1 : -1; |
| // subtracting 1 from the number of days, because counting |
| // from end of given day, so it counts for day 1 |
| // cal.add(Calendar.DATE, sign * (d.getDays()-1)); |
| // "(date('2002-08-05')-duration('P42D'))+duration('P42D') = date('2002-08-05')" |
| // doesn't work if you do the -1. It sure feels like that is wrong. |
| // -sb |
| double secs = d.getSeconds() + (((((d.getDays() * 24) + d.getHours()) * 60) + d.getMinutes()) * 60); |
| cal.add(Calendar.SECOND , sign * (new Double (Math.floor(secs)).intValue())); |
| |
| DateTimeObj dt = date(cal.getTime()); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| /** |
| * Method subtractDateFromDate. |
| * @param date2 |
| * @return Duration |
| * @throws TransformerException |
| */ |
| public Duration subtractDateFromDate(DateTimeObj date2) |
| throws TransformerException |
| { |
| |
| /*Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| |
| int year = m_year - date2.m_year; |
| int month = m_month - date2.m_month; |
| int day = m_day - date2.m_day; |
| int hour = m_hour - date2.m_hour; |
| int minute = m_minute - date2.m_minute; |
| double second = m_second - date2.m_second; |
| |
| Duration dur = new Duration(year, month, day, hour, minute, second); |
| |
| return dur;*/ |
| return getDTDuration(date2); |
| } |
| |
| |
| |
| public DateTimeObj subtractDTDurationFromTime(Duration d) |
| throws TransformerException |
| { |
| Calendar cal = Calendar.getInstance(); |
| cal.setLenient(false); |
| cal.setTime(m_date); |
| int sign = (d.getSigned()) ? 1 : -1; |
| double secs = d.getSeconds() + ((((d.getHours()) * 60) + d.getMinutes()) * 60); |
| cal.add(Calendar.SECOND , sign * (new Double(Math.floor(secs)).intValue())); |
| |
| DateTimeObj dt = time(cal.getTime()); |
| dt.setZone(m_zone); |
| return dt; |
| } |
| |
| |
| |
| public void setYears(int years) |
| { |
| m_year = years; |
| } |
| |
| public int getYears() |
| { |
| return m_year; |
| } |
| |
| public void setMonths(int months) |
| { |
| m_month = months; |
| } |
| |
| public int getMonths() |
| { |
| return m_month; |
| } |
| |
| public void setDays(int days) |
| { |
| m_day = days; |
| } |
| |
| public int getDays() |
| { |
| return m_day; |
| } |
| |
| public void setHours(int hours) |
| { |
| m_hour = hours; |
| } |
| |
| public int getHours() |
| { |
| return m_hour; |
| } |
| |
| public void setSeconds(double secs) |
| { |
| m_second = secs; |
| } |
| |
| public double getSeconds() |
| { |
| return m_second; |
| } |
| |
| public void setMinutes(int mts) |
| { |
| m_minute = mts; |
| } |
| |
| public int getMinutes() |
| { |
| return m_minute; |
| } |
| |
| public void setZone(String zone) |
| { |
| m_zone = zone; |
| } |
| |
| public String getZone() |
| { |
| if (m_zone.equals("Z") ) |
| return ("00:00"); |
| else |
| return m_zone; |
| } |
| |
| public Date getDate() |
| { |
| return m_date; |
| } |
| |
| public String toString() |
| { |
| return (m_dateTime + (m_zone == null ? "" : m_zone)); |
| } |
| |
| |
| |
| } |