@@ -256,14 +256,20 @@ def to_ds(obj: TimeLike) -> str:
256256 return to_ts (obj )[0 :10 ]
257257
258258
259- def to_ts (obj : TimeLike ) -> str :
259+ def to_ts (obj : TimeLike , include_microseconds : bool = True ) -> str :
260260 """Converts a TimeLike object into YYYY-MM-DD HH:MM:SS formatted string."""
261- return to_datetime (obj ).replace (tzinfo = None ).isoformat (sep = " " )
261+ obj_dt = to_datetime (obj )
262+ if not include_microseconds :
263+ obj_dt = obj_dt .replace (microsecond = 0 )
264+ return obj_dt .replace (tzinfo = None ).isoformat (sep = " " )
262265
263266
264- def to_tstz (obj : TimeLike ) -> str :
267+ def to_tstz (obj : TimeLike , include_microseconds : bool = True ) -> str :
265268 """Converts a TimeLike object into YYYY-MM-DD HH:MM:SS+00:00 formatted string."""
266- return to_datetime (obj ).isoformat (sep = " " )
269+ obj_dt = to_datetime (obj )
270+ if not include_microseconds :
271+ obj_dt = obj_dt .replace (microsecond = 0 )
272+ return obj_dt .isoformat (sep = " " )
267273
268274
269275def is_date (obj : TimeLike ) -> bool :
@@ -289,7 +295,7 @@ def make_inclusive(start: TimeLike, end: TimeLike) -> Interval:
289295 In the ds ('2020-01-01') case, because start_ds and end_ds are categorical, between works even if
290296 start_ds and end_ds are equivalent. However, when we move to ts ('2022-01-01 12:00:00'), because timestamps
291297 are numeric, using simple equality doesn't make sense. When the end is not a categorical date, then it is
292- treated as an exclusive range and converted to inclusive by subtracting 1 millisecond .
298+ treated as an exclusive range and converted to inclusive by subtracting 1 microsecond .
293299
294300 Args:
295301 start: Start timelike object.
@@ -347,16 +353,22 @@ def to_time_column(
347353 time_column : t .Union [TimeLike , exp .Null ],
348354 time_column_type : exp .DataType ,
349355 time_column_format : t .Optional [str ] = None ,
356+ include_microseconds : bool = True ,
350357) -> exp .Expression :
351358 """Convert a TimeLike object to the same time format and type as the model's time column."""
352359 if isinstance (time_column , exp .Null ):
353360 return exp .cast (time_column , to = time_column_type )
354361 if time_column_type .is_type (exp .DataType .Type .DATE ):
355362 return exp .cast (exp .Literal .string (to_ds (time_column )), to = "date" )
356363 if time_column_type .is_type (* TEMPORAL_TZ_TYPES ):
357- return exp .cast (exp .Literal .string (to_tstz (time_column )), to = time_column_type )
364+ return exp .cast (
365+ exp .Literal .string (to_tstz (time_column , include_microseconds )),
366+ to = time_column_type ,
367+ )
358368 if time_column_type .is_type (* exp .DataType .TEMPORAL_TYPES ):
359- return exp .cast (exp .Literal .string (to_ts (time_column )), to = time_column_type )
369+ return exp .cast (
370+ exp .Literal .string (to_ts (time_column , include_microseconds )), to = time_column_type
371+ )
360372
361373 if time_column_format :
362374 time_column = to_datetime (time_column ).strftime (time_column_format )
0 commit comments