/**
   * 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;
  }