diff --git a/src/query/expression/src/utils/date_helper.rs b/src/query/expression/src/utils/date_helper.rs index 175d63e185e97..ad27540e8e9e2 100644 --- a/src/query/expression/src/utils/date_helper.rs +++ b/src/query/expression/src/utils/date_helper.rs @@ -243,6 +243,7 @@ impl TzLUT { pub trait DateConverter { fn to_date(&self, tz: Tz) -> NaiveDate; fn to_timestamp(&self, tz: Tz) -> DateTime; + fn convert_timezone(&self, target_tz: Tz, src_timestamp: DateTime, src_tz: Option, src_ntz_timestamp: Option>) -> DateTime; } impl DateConverter for T @@ -264,6 +265,31 @@ where T: AsPrimitive } tz.timestamp_opt(secs, nanos as u32).unwrap() } + /// Convert a timestamp to the specify timezone. + /// + /// # Parameters + /// - `target_tz`: Timezone in which the timestamp will be converted + /// - `src_timestamp`: Source timestamp to be converted + /// - `src_tz`: Timezone of the timestamp to be converted - Optional + /// - `src_ntz_timestamp`: Source timestamp with unspecified timezone to be converted - Optional + fn convert_timezone(&self, target_tz: Tz, src_timestamp: DateTime, src_tz: Option, src_ntz_timestamp: Option) -> DateTime { + + let timestamp_to_convert: DateTime; + if let (Some(ntz_timestamp), Some(tz)) = (src_ntz_timestamp, src_tz) { + timestamp_to_convert = tz.from_local_datetime(&ntz_timestamp).unwrap(); + } + else { + timestamp_to_convert = src_timestamp; + } + + if timestamp_to_convert.timezone() != target_tz { + timestamp_to_convert.with_timezone(&target_tz) + } + else { + timestamp_to_convert + } + + } } pub const MICROSECS_PER_DAY: i64 = 86_400_000_000;