11use chrono:: { DateTime , Duration , LocalResult , NaiveDate , NaiveDateTime , TimeZone } ;
22use chrono_tz:: Tz ;
33use cubenativeutils:: CubeError ;
4+ use lazy_static:: lazy_static;
45use regex:: Regex ;
6+
57pub struct QueryDateTimeHelper { }
68
7- use lazy_static:: lazy_static;
89lazy_static ! {
910 static ref DATE_TIME_LOCAL_MS_RE : Regex =
1011 Regex :: new( r"^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\d$" ) . unwrap( ) ;
1112 static ref DATE_TIME_LOCAL_U_RE : Regex =
1213 Regex :: new( r"^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d\.\d\d\d\d\d\d$" ) . unwrap( ) ;
1314 static ref DATE_RE : Regex = Regex :: new( r"^\d\d\d\d-\d\d-\d\d$" ) . unwrap( ) ;
1415}
16+
1517impl QueryDateTimeHelper {
1618 pub fn parse_native_date_time ( date : & str ) -> Result < NaiveDateTime , CubeError > {
1719 let formats = & [
@@ -28,8 +30,9 @@ impl QueryDateTimeHelper {
2830 }
2931 }
3032
31- if let Ok ( d) = NaiveDate :: parse_from_str ( date, "%Y-%m-%d" ) {
32- return Ok ( d. and_hms_opt ( 0 , 0 , 0 ) . unwrap ( ) ) ;
33+ // Fallback as RFC3339/ISO8601 with 'Z' timezone
34+ if let Ok ( dt) = DateTime :: parse_from_rfc3339 ( date) {
35+ return Ok ( dt. naive_utc ( ) ) ;
3336 }
3437
3538 Err ( CubeError :: user ( format ! ( "Can't parse date: '{}'" , date) ) )
@@ -190,5 +193,20 @@ mod tests {
190193 . and_hms_milli_opt( 12 , 10 , 15 , 345 )
191194 . unwrap( )
192195 ) ;
196+ // Test parsing with 'Z' timezone (UTC)
197+ assert_eq ! (
198+ QueryDateTimeHelper :: parse_native_date_time( "2024-01-01T10:15:00Z" ) . unwrap( ) ,
199+ NaiveDate :: from_ymd_opt( 2024 , 1 , 1 )
200+ . unwrap( )
201+ . and_hms_opt( 10 , 15 , 0 )
202+ . unwrap( )
203+ ) ;
204+ assert_eq ! (
205+ QueryDateTimeHelper :: parse_native_date_time( "2024-01-01T10:15:00.123Z" ) . unwrap( ) ,
206+ NaiveDate :: from_ymd_opt( 2024 , 1 , 1 )
207+ . unwrap( )
208+ . and_hms_milli_opt( 10 , 15 , 0 , 123 )
209+ . unwrap( )
210+ ) ;
193211 }
194212}
0 commit comments