/** * Return a new dateTime with the same normalized value, but in a different timezone. * * @param timezone the new timezone offset, in minutes * @return the date/time in the new timezone. This will be a new DateTimeValue unless no change * was required to the original value */ public CalendarValue adjustTimezone(int timezone) { if (!hasTimezone()) { CalendarValue in = (CalendarValue) copyAsSubType(typeLabel); in.setTimezoneInMinutes(timezone); return in; } int oldtz = getTimezoneInMinutes(); if (oldtz == timezone) { return this; } int tz = timezone - oldtz; int h = hour; int mi = minute; mi += tz; if (mi < 0 || mi > 59) { h += Math.floor(mi / 60.0); mi = (mi + 60 * 24) % 60; } if (h >= 0 && h < 24) { return new DateTimeValue( year, month, day, (byte) h, (byte) mi, second, microsecond, timezone); } // Following code is designed to handle the corner case of adjusting from -14:00 to +14:00 or // vice versa, which can cause a change of two days in the date DateTimeValue dt = this; while (h < 0) { h += 24; DateValue t = DateValue.yesterday(dt.getYear(), dt.getMonth(), dt.getDay()); dt = new DateTimeValue( t.getYear(), t.getMonth(), t.getDay(), (byte) h, (byte) mi, second, microsecond, timezone); } if (h > 23) { h -= 24; DateValue t = DateValue.tomorrow(year, month, day); return new DateTimeValue( t.getYear(), t.getMonth(), t.getDay(), (byte) h, (byte) mi, second, microsecond, timezone); } return dt; }
/** * Compare the value to another dateTime value, following the XPath comparison semantics * * @param other The other dateTime value * @param context XPath dynamic evaluation context * @return negative value if this one is the earler, 0 if they are chronologically equal, positive * value if this one is the later. For this purpose, dateTime values with an unknown timezone * are considered to be values in the implicit timezone (the Comparable interface requires a * total ordering). * @throws ClassCastException if the other value is not a DateTimeValue (the parameter is declared * as CalendarValue to satisfy the interface) * @throws NoDynamicContextException if the implicit timezone is needed and is not available */ public int compareTo(CalendarValue other, XPathContext context) throws NoDynamicContextException { if (!(other instanceof DateTimeValue)) { throw new ClassCastException("DateTime values are not comparable to " + other.getClass()); } DateTimeValue v2 = (DateTimeValue) other; if (getTimezoneInMinutes() == v2.getTimezoneInMinutes()) { // both values are in the same timezone (explicitly or implicitly) if (year != v2.year) { return IntegerValue.signum(year - v2.year); } if (month != v2.month) { return IntegerValue.signum(month - v2.month); } if (day != v2.day) { return IntegerValue.signum(day - v2.day); } if (hour != v2.hour) { return IntegerValue.signum(hour - v2.hour); } if (minute != v2.minute) { return IntegerValue.signum(minute - v2.minute); } if (second != v2.second) { return IntegerValue.signum(second - v2.second); } if (microsecond != v2.microsecond) { return IntegerValue.signum(microsecond - v2.microsecond); } return 0; } return normalize(context).compareTo(v2.normalize(context), context); }