/**
   * Factory method: create a dateTime value given a date and a time.
   *
   * @param date the date
   * @param time the time
   * @return the dateTime with the given components. If either component is null, returns null
   * @throws XPathException if the timezones are both present and inconsistent
   */
  public static DateTimeValue makeDateTimeValue(DateValue date, TimeValue time)
      throws XPathException {
    if (date == null || time == null) {
      return null;
    }
    DayTimeDurationValue tz1 = (DayTimeDurationValue) date.getComponent(Component.TIMEZONE);
    DayTimeDurationValue tz2 = (DayTimeDurationValue) time.getComponent(Component.TIMEZONE);
    boolean zoneSpecified = (tz1 != null || tz2 != null);
    if (tz1 != null && tz2 != null && !tz1.equals(tz2)) {
      XPathException err = new XPathException("Supplied date and time are in different timezones");
      err.setErrorCode("FORG0008");
      throw err;
    }

    DateTimeValue v = new DateTimeValue();
    v.year = (int) ((Int64Value) date.getComponent(Component.YEAR_ALLOWING_ZERO)).longValue();
    v.month = (byte) ((Int64Value) date.getComponent(Component.MONTH)).longValue();
    v.day = (byte) ((Int64Value) date.getComponent(Component.DAY)).longValue();
    v.hour = (byte) ((Int64Value) time.getComponent(Component.HOURS)).longValue();
    v.minute = (byte) ((Int64Value) time.getComponent(Component.MINUTES)).longValue();
    final BigDecimal secs = ((DecimalValue) time.getComponent(Component.SECONDS)).getDecimalValue();
    v.second = (byte) secs.intValue();
    v.microsecond = secs.multiply(BigDecimal.valueOf(1000000)).intValue() % 1000000;
    if (zoneSpecified) {
      if (tz1 == null) {
        tz1 = tz2;
      }
      v.setTimezoneInMinutes((int) (tz1.getLengthInMicroseconds() / 60000000));
    }
    v.typeLabel = BuiltInAtomicType.DATE_TIME;
    return v;
  }
 /**
  * Get a component of the value. Returns null if the timezone component is requested and is not
  * present.
  */
 public AtomicValue getComponent(int component) throws XPathException {
   switch (component) {
     case Component.YEAR_ALLOWING_ZERO:
       return Int64Value.makeIntegerValue(year);
     case Component.YEAR:
       return Int64Value.makeIntegerValue(year > 0 ? year : year - 1);
     case Component.MONTH:
       return Int64Value.makeIntegerValue(month);
     case Component.DAY:
       return Int64Value.makeIntegerValue(day);
     case Component.HOURS:
       return Int64Value.makeIntegerValue(hour);
     case Component.MINUTES:
       return Int64Value.makeIntegerValue(minute);
     case Component.SECONDS:
       BigDecimal d = BigDecimal.valueOf(microsecond);
       d = d.divide(DecimalValue.BIG_DECIMAL_ONE_MILLION, 6, BigDecimal.ROUND_HALF_UP);
       d = d.add(BigDecimal.valueOf(second));
       return new DecimalValue(d);
     case Component.WHOLE_SECONDS: // (internal use only)
       return Int64Value.makeIntegerValue(second);
     case Component.MICROSECONDS:
       // internal use only
       return new Int64Value(microsecond);
     case Component.TIMEZONE:
       if (hasTimezone()) {
         return DayTimeDurationValue.fromMilliseconds(getTimezoneInMinutes() * 60 * 1000);
       } else {
         return null;
       }
     default:
       throw new IllegalArgumentException("Unknown component for dateTime: " + component);
   }
 }
 /**
  * Factory method: create a dateTime value given a Java Date object. The returned dateTime value
  * will always have a timezone, which will always be UTC.
  *
  * @param suppliedDate holds the date and time
  * @return the corresponding xs:dateTime value
  */
 public static DateTimeValue fromJavaDate(Date suppliedDate) throws XPathException {
   long millis = suppliedDate.getTime();
   return (DateTimeValue) EPOCH.add(DayTimeDurationValue.fromMilliseconds(millis));
 }