@@ -253,17 +253,20 @@ static TypeDescriptor<?> createDateDescriptor() {
253253 if (val instanceof Date ) {
254254 sqlDate = (Date ) val ;
255255 } else if (val instanceof Timestamp ) {
256- sqlDate = Date .valueOf (((Timestamp ) val ).toLocalDateTime ().toLocalDate ());
256+ ZoneId targetZone = zone != null ? zone : ZoneId .systemDefault ();
257+ LocalDate localDate = ((Timestamp ) val ).toInstant ().atZone (targetZone ).toLocalDate ();
258+ sqlDate = BigQueryTemporalUtility .boxDate (localDate , zone );
257259 } else if (val instanceof java .sql .Time ) {
258260 throw new BigQueryJdbcException ("Cannot convert to DATE: " + val );
259261 } else if (val instanceof java .util .Date ) {
260262 sqlDate = new Date (((java .util .Date ) val ).getTime ());
261263 } else if (val instanceof LocalDate ) {
262- sqlDate = Date . valueOf ((LocalDate ) val );
264+ sqlDate = BigQueryTemporalUtility . boxDate ((LocalDate ) val , zone );
263265 } else if (val instanceof LocalDateTime ) {
264- sqlDate = Date . valueOf (((LocalDateTime ) val ).toLocalDate ());
266+ sqlDate = BigQueryTemporalUtility . boxDate (((LocalDateTime ) val ).toLocalDate (), zone );
265267 } else if (val instanceof Integer ) {
266- sqlDate = Date .valueOf (LocalDate .ofEpochDay (((Integer ) val ).longValue ()));
268+ LocalDate localDate = LocalDate .ofEpochDay (((Integer ) val ).longValue ());
269+ sqlDate = BigQueryTemporalUtility .boxDate (localDate , zone );
267270 } else if (val instanceof String ) {
268271 sqlDate = BigQueryTemporalUtility .boxDate ((String ) val , zone );
269272 } else {
@@ -303,7 +306,7 @@ static TypeDescriptor<?> createDatetimeDescriptor() {
303306 } else if (val instanceof java .util .Date ) {
304307 ts = new Timestamp (((java .util .Date ) val ).getTime ());
305308 } else if (val instanceof LocalDateTime ) {
306- ts = Timestamp . valueOf ((LocalDateTime ) val );
309+ ts = BigQueryTemporalUtility . boxDateTime ((LocalDateTime ) val , zone );
307310 } else if (val instanceof String ) {
308311 ts = BigQueryTemporalUtility .boxDateTime ((String ) val , zone );
309312 } else {
@@ -408,13 +411,16 @@ static TypeDescriptor<?> createTimeDescriptor() {
408411 Time sqlTime ;
409412 if (val instanceof Time ) sqlTime = (Time ) val ;
410413 else if (val instanceof Timestamp ) {
411- sqlTime = Time .valueOf (((Timestamp ) val ).toLocalDateTime ().toLocalTime ());
414+ ZoneId targetZone = zone != null ? zone : ZoneId .systemDefault ();
415+ LocalTime localTime = ((Timestamp ) val ).toInstant ().atZone (targetZone ).toLocalTime ();
416+ sqlTime = BigQueryTemporalUtility .boxTime (localTime , zone );
412417 } else if (val instanceof java .sql .Date ) {
413418 throw new BigQueryJdbcException ("Cannot convert to TIME: " + val );
414419 } else if (val instanceof java .util .Date )
415420 sqlTime = new Time (((java .util .Date ) val ).getTime ());
416- else if (val instanceof LocalTime ) sqlTime = Time .valueOf ((LocalTime ) val );
417- else if (val instanceof LocalDateTime ) {
421+ else if (val instanceof LocalTime ) {
422+ sqlTime = BigQueryTemporalUtility .boxTime ((LocalTime ) val , zone );
423+ } else if (val instanceof LocalDateTime ) {
418424 long millisOfDay = ((LocalDateTime ) val ).toLocalTime ().toNanoOfDay () / 1_000_000 ;
419425 sqlTime = new Time (BigQueryTemporalUtility .getLocalMillis (millisOfDay , zone ));
420426 } else if (val instanceof Long ) {
@@ -772,12 +778,28 @@ public static <T> T convert(
772778 if (input == null ) {
773779 return null ;
774780 }
781+ if (input instanceof FieldValue ) {
782+ FieldValue fv = (FieldValue ) input ;
783+ if (fv .isNull ()) {
784+ return null ;
785+ }
786+ input = fv .getValue ();
787+ }
775788 int ordinal = bqType .ordinal ();
776789 if (ordinal >= DESCRIPTORS_BY_ORDINAL .length || DESCRIPTORS_BY_ORDINAL [ordinal ] == null ) {
777790 throw new BigQueryJdbcException ("No type descriptor registered for BigQuery type: " + bqType );
778791 }
792+ ZoneId effectiveZone = (bqType == StandardSQLTypeName .TIMESTAMP ) ? null : zoneId ;
779793 try {
780- return (T ) DESCRIPTORS_BY_ORDINAL [ordinal ].convert (input , targetClass , zoneId );
794+ Object result = DESCRIPTORS_BY_ORDINAL [ordinal ].convert (input , targetClass , effectiveZone );
795+ if (!targetClass .isInstance (result )) {
796+ TypeDescriptor <?> targetDescriptor = getDescriptorForClass (targetClass );
797+ if (targetDescriptor == null ) {
798+ throw new BigQueryJdbcException ("Unsupported target class: " + targetClass .getName ());
799+ }
800+ result = targetDescriptor .convert (result , targetClass , effectiveZone );
801+ }
802+ return (T ) result ;
781803 } catch (Exception e ) {
782804 throw new BigQueryJdbcException (
783805 String .format (
0 commit comments