001: package net.sf.saxon.functions;
002:
003: import net.sf.saxon.expr.Expression;
004: import net.sf.saxon.expr.StaticContext;
005: import net.sf.saxon.expr.XPathContext;
006: import net.sf.saxon.om.Item;
007: import net.sf.saxon.trans.XPathException;
008: import net.sf.saxon.trans.DynamicError;
009: import net.sf.saxon.value.AtomicValue;
010: import net.sf.saxon.value.CalendarValue;
011: import net.sf.saxon.value.SecondsDurationValue;
012:
013: /**
014: * This class implements the XPath 2.0 functions
015: * adjust-date-to-timezone(), adjust-time-timezone(), and adjust-dateTime-timezone().
016: */
017:
018: public class Adjust extends SystemFunction {
019:
020: int implicitTimezone; // implicit timezone as offset from UTC in minutes
021:
022: /**
023: * Simplify and validate.
024: */
025:
026: public Expression simplify(StaticContext env) throws XPathException {
027: implicitTimezone = env.getConfiguration().getImplicitTimezone();
028: return super .simplify(env);
029: }
030:
031: /**
032: * Evaluate in a general context
033: */
034:
035: public Item evaluateItem(XPathContext context)
036: throws XPathException {
037: AtomicValue av1 = (AtomicValue) argument[0]
038: .evaluateItem(context);
039: if (av1 == null) {
040: return null;
041: }
042: CalendarValue in = (CalendarValue) av1.getPrimitiveValue();
043:
044: int nargs = argument.length;
045: SecondsDurationValue tz;
046: if (nargs == 1) {
047: // use the implicit timezone
048: // if (in.hasTimezone()) {
049: return in.adjustTimezone(implicitTimezone);
050: // } else {
051: // in = in.copy();
052: // in.setTimezoneInMinutes(implicitTimezone);
053: // return in;
054: // }
055: } else {
056: AtomicValue av2 = (AtomicValue) argument[1]
057: .evaluateItem(context);
058: if (av2 == null) {
059: return in.removeTimezone();
060: }
061: tz = (SecondsDurationValue) av2.getPrimitiveValue();
062: long microseconds = tz.getLengthInMicroseconds();
063: if (microseconds % 60000000 != 0) {
064: DynamicError err = new DynamicError(
065: "Timezone is not an integral number of minutes");
066: err.setErrorCode("FODT0003");
067: err.setLocator(this );
068: err.setXPathContext(context);
069: throw err;
070: }
071: int tzminutes = (int) (microseconds / 60000000);
072: if (Math.abs(tzminutes) > 14 * 60) {
073: DynamicError err = new DynamicError(
074: "Timezone out of range (-14:00 to +14:00)");
075: err.setErrorCode("FODT0003");
076: err.setLocator(this );
077: err.setXPathContext(context);
078: throw err;
079: }
080: // if (in.hasTimezone()) {
081: return in.adjustTimezone(tzminutes);
082: // } else {
083: // in = in.copy();
084: // in.setTimezoneInMinutes(tzminutes);
085: // return in;
086: // }
087: }
088: }
089:
090: }
091:
092: //
093: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
094: // you may not use this file except in compliance with the License. You may obtain a copy of the
095: // License at http://www.mozilla.org/MPL/
096: //
097: // Software distributed under the License is distributed on an "AS IS" basis,
098: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
099: // See the License for the specific language governing rights and limitations under the License.
100: //
101: // The Original Code is: all this file.
102: //
103: // The Initial Developer of the Original Code is Michael H. Kay.
104: //
105: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
106: //
107: // Contributor(s): none.
108: //
|