/**
  * INTERNAL: Appends an Oracle specific Timestamp with timezone and daylight time elements if
  * usesNativeSQL is true, otherwise use the ODBC format. Native Format: (DST) to_timestamp_tz
  * ('1997-11-06 10:35:45.345 America/Los_Angeles','yyyy-mm-dd hh:mm:ss.ff TZR TZD') (non-DST)
  * to_timestamp_tz ('1997-11-06 10:35:45.345 America/Los_Angeles','yyyy-mm-dd hh:mm:ss.ff TZR')
  */
 protected void appendCalendar(Calendar calendar, Writer writer) throws IOException {
   if (usesNativeSQL()) {
     writer.write("to_timestamp_tz('");
     writer.write(TIMESTAMPHelper.printCalendar(calendar));
     // append TZD element if the calendar's timezone is in daylight time
     if (TIMESTAMPHelper.shouldAppendDaylightTime(calendar)) {
       writer.write("','yyyy-mm-dd HH24:MI:SS.FF TZR TZD')");
     } else {
       writer.write("','yyyy-mm-dd HH24:MI:SS.FF TZR')");
     }
   } else {
     super.appendCalendar(calendar, writer);
   }
 }
 /**
  * INTERNAL: Note that index (not index+1) is used in statement.setObject(index, parameter)
  * Binding starts with a 1 not 0, so make sure that index > 0. Treat Calendar separately. Bind
  * Calendar as TIMESTAMPTZ.
  */
 public void setParameterValueInDatabaseCall(
     Object parameter, PreparedStatement statement, int index, AbstractSession session)
     throws SQLException {
   if (parameter instanceof Calendar) {
     Calendar calendar = (Calendar) parameter;
     Connection conn = getConnection(session, statement.getConnection());
     TIMESTAMPTZ tsTZ =
         TIMESTAMPHelper.buildTIMESTAMPTZ(calendar, conn, shouldPrintCalendar(conn));
     statement.setObject(index, tsTZ);
   } else {
     super.setParameterValueInDatabaseCall(parameter, statement, index, session);
   }
 }
  /** INTERNAL: Allow for conversion from the Oracle type to the Java type. */
  public Object convertObject(Object sourceObject, Class javaClass)
      throws ConversionException, DatabaseException {
    if ((javaClass == null) || ((sourceObject != null) && (sourceObject.getClass() == javaClass))) {
      return sourceObject;
    }

    Object valueToConvert = sourceObject;

    // Used in Type Conversion Mapping on write
    if ((javaClass == TIMESTAMPTypes.TIMESTAMP_CLASS)
        || (javaClass == TIMESTAMPTypes.TIMESTAMPLTZ_CLASS)) {
      return sourceObject;
    }

    if (javaClass == TIMESTAMPTypes.TIMESTAMPTZ_CLASS) {
      if (sourceObject instanceof java.util.Date) {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(((java.util.Date) sourceObject).getTime());
        return cal;
      } else {
        return sourceObject;
      }
    }

    if (javaClass == XMLTYPE) {
      // Don't convert to XMLTypes. This will be done by the
      // XMLTypeBindCallCustomParameter to ensure the correct
      // Connection is used
      return sourceObject;
    }

    // Added to overcome an issue with the oracle 9.0.1.1.0 JDBC driver.
    if (sourceObject instanceof TIMESTAMP) {
      try {
        valueToConvert = ((TIMESTAMP) sourceObject).timestampValue();
      } catch (SQLException exception) {
        throw DatabaseException.sqlException(exception);
      }
    } else if (sourceObject instanceof TIMESTAMPTZWrapper) {
      // Bug#4364359 Used when database type is TIMESTAMPTZ.  Timestamp and session timezone are
      // wrapped
      // in TIMESTAMPTZWrapper.  Separate Calendar from any other types.
      if (((javaClass == ClassConstants.CALENDAR)
          || (javaClass == ClassConstants.GREGORIAN_CALENDAR))) {
        try {
          return TIMESTAMPHelper.buildCalendar((TIMESTAMPTZWrapper) sourceObject);
        } catch (SQLException exception) {
          throw DatabaseException.sqlException(exception);
        }
      } else {
        // If not using native sql, Calendar will be converted to Timestamp just as
        // other date time types
        valueToConvert = ((TIMESTAMPTZWrapper) sourceObject).getTimestamp();
      }
    } else if (sourceObject instanceof TIMESTAMPLTZWrapper) {
      // Bug#4364359 Used when database type is TIMESTAMPLTZ.  Timestamp and session timezone id are
      // wrapped
      // in TIMESTAMPLTZWrapper.  Separate Calendar from any other types.
      if (((javaClass == ClassConstants.CALENDAR)
          || (javaClass == ClassConstants.GREGORIAN_CALENDAR))) {
        try {
          return TIMESTAMPHelper.buildCalendar((TIMESTAMPLTZWrapper) sourceObject);
        } catch (SQLException exception) {
          throw DatabaseException.sqlException(exception);
        }
      } else {
        // If not using native sql, Calendar will be converted to Timestamp just as
        // other date time types
        valueToConvert = ((TIMESTAMPLTZWrapper) sourceObject).getTimestamp();
      }
    }

    return super.convertObject(valueToConvert, javaClass);
  }