diff --git a/crates/polars-core/src/datatypes/dtype.rs b/crates/polars-core/src/datatypes/dtype.rs index d3caafdbfe79..b06f49a53c67 100644 --- a/crates/polars-core/src/datatypes/dtype.rs +++ b/crates/polars-core/src/datatypes/dtype.rs @@ -717,6 +717,8 @@ impl DataType { UInt64 => Scalar::from(u64::MAX), Float32 => Scalar::from(f32::INFINITY), Float64 => Scalar::from(f64::INFINITY), + #[cfg(feature = "dtype-time")] + Time => Scalar::new(Time, AnyValue::Time(NS_IN_DAY - 1)), dt => polars_bail!(ComputeError: "cannot determine upper bound for dtype `{}`", dt), }; Ok(v) @@ -737,6 +739,8 @@ impl DataType { UInt64 => Scalar::from(u64::MIN), Float32 => Scalar::from(f32::NEG_INFINITY), Float64 => Scalar::from(f64::NEG_INFINITY), + #[cfg(feature = "dtype-time")] + Time => Scalar::new(Time, AnyValue::Time(0)), dt => polars_bail!(ComputeError: "cannot determine lower bound for dtype `{}`", dt), }; Ok(v) diff --git a/py-polars/polars/datatypes/classes.py b/py-polars/polars/datatypes/classes.py index 568b67bfde2f..707468a2d9ff 100644 --- a/py-polars/polars/datatypes/classes.py +++ b/py-polars/polars/datatypes/classes.py @@ -448,6 +448,44 @@ class Time(TemporalType): The integer indicates the number of nanoseconds since midnight. """ + @classmethod + def max(cls) -> pl.Expr: + """ + Return a literal expression representing the maximum value of this data type. + + Examples + -------- + >>> pl.select(pl.Time.max() == 86_399_999_999_999) + shape: (1, 1) + ┌─────────┐ + │ literal │ + │ --- │ + │ bool │ + ╞═════════╡ + │ true │ + └─────────┘ + """ + return pl.Expr._from_pyexpr(plr._get_dtype_max(cls)) + + @classmethod + def min(cls) -> pl.Expr: + """ + Return a literal expression representing the minimum value of this data type. + + Examples + -------- + >>> pl.select(pl.Time.min() == 0) + shape: (1, 1) + ┌─────────┐ + │ literal │ + │ --- │ + │ bool │ + ╞═════════╡ + │ true │ + └─────────┘ + """ + return pl.Expr._from_pyexpr(plr._get_dtype_min(cls)) + class Datetime(TemporalType): """ diff --git a/py-polars/tests/unit/test_datatypes.py b/py-polars/tests/unit/test_datatypes.py index ed4b8cd1dd61..61be9aff904d 100644 --- a/py-polars/tests/unit/test_datatypes.py +++ b/py-polars/tests/unit/test_datatypes.py @@ -1,7 +1,7 @@ from __future__ import annotations import pickle -from datetime import datetime, timedelta +from datetime import datetime, time, timedelta from typing import TYPE_CHECKING import pytest @@ -217,12 +217,16 @@ def test_raise_invalid_namespace() -> None: (pl.UInt64, 0, 18446744073709551615), (pl.Float32, float("-inf"), float("inf")), (pl.Float64, float("-inf"), float("inf")), + (pl.Time, time(0, 0), time(23, 59, 59, 999999)), ], ) def test_max_min( - dtype: datatypes.IntegerType | datatypes.Float32 | datatypes.Float64, - upper: int | float, - lower: int | float, + dtype: datatypes.IntegerType + | datatypes.Float32 + | datatypes.Float64 + | datatypes.Time, + upper: int | float | time, + lower: int | float | time, ) -> None: df = pl.select(min=dtype.min(), max=dtype.max()) assert df.to_series(0).item() == lower