@@ -79,11 +79,15 @@ fn get_timestamp_decoder<T: ArrowTimestampType + Send>(
7979 let inner = get_inner_timestamp_decoder :: < T > ( column, stripe, seconds_since_unix_epoch) ;
8080 match stripe. writer_tz ( ) {
8181 Some ( writer_tz) => {
82- let reader_tz = iana_time_zone:: get_timezone ( ) . ok ( ) ;
83- let has_same_tz_rules = reader_tz == Some ( writer_tz. name ( ) . to_string ( ) ) ;
82+ // Get reader timezone, default to UTC if not available
83+ let reader_tz_name =
84+ iana_time_zone:: get_timezone ( ) . unwrap_or_else ( |_| "UTC" . to_string ( ) ) ;
85+ let reader_tz = reader_tz_name. parse :: < chrono_tz:: Tz > ( ) . unwrap_or ( UTC ) ;
86+ let has_same_tz_rules = writer_tz == reader_tz;
8487 Box :: new ( TimestampOffsetArrayDecoder {
8588 inner,
8689 writer_tz,
90+ reader_tz,
8791 has_same_tz_rules,
8892 } )
8993 }
@@ -240,10 +244,11 @@ pub fn new_timestamp_instant_decoder(
240244}
241245
242246/// Wrapper around PrimitiveArrayDecoder to decode timestamps which are encoded in
243- /// timezone of the writer to their UTC value .
247+ /// timezone of the writer to reader timezone .
244248struct TimestampOffsetArrayDecoder < T : ArrowTimestampType > {
245249 inner : PrimitiveArrayDecoder < T > ,
246250 writer_tz : chrono_tz:: Tz ,
251+ reader_tz : chrono_tz:: Tz ,
247252 has_same_tz_rules : bool ,
248253}
249254
@@ -264,11 +269,26 @@ impl<T: ArrowTimestampType> ArrayBatchDecoder for TimestampOffsetArrayDecoder<T>
264269 if self . has_same_tz_rules {
265270 return Some ( ts) ;
266271 }
272+
273+ // Convert timestamp from writer timezone to reader timezone
274+ // 1. Interpret the timestamp as being in the writer timezone
275+ // 2. Convert to UTC
276+ // 3. Convert to reader timezone
277+ // 4. Get the timestamp in nanoseconds
278+ // self.writer_tz
279+ // .timestamp_nanos(ts)
280+ // .naive_local()
281+ // .and_utc()
282+ // .with_timezone(&self.reader_tz)
283+ // .timestamp_nanos_opt()
267284 self . writer_tz
268285 . timestamp_nanos ( ts)
269286 . naive_local ( )
270287 . and_utc ( )
271- . timestamp_nanos_opt ( )
288+ . naive_local ( )
289+ . and_local_timezone ( self . reader_tz )
290+ . single ( )
291+ . and_then ( |dt_in_reader_tz| dt_in_reader_tz. timestamp_nanos_opt ( ) )
272292 } ;
273293 let array = array
274294 // first try to convert all non-nullable batches to non-nullable batches
0 commit comments