Skip to content

narwhals.Expr.dt

convert_time_zone(time_zone)

Convert to a new time zone.

If converting from a time-zone-naive column, then conversion happens as if converting from UTC.

Parameters:

Name Type Description Default
time_zone str

Target time zone.

required

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> from datetime import datetime, timezone
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> data = {
...     "a": [
...         datetime(2024, 1, 1, tzinfo=timezone.utc),
...         datetime(2024, 1, 2, tzinfo=timezone.utc),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)
>>> df_pa = pa.table(data)

Let's define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.select(
...         nw.col("a").dt.convert_time_zone("Asia/Kathmandu")
...     ).to_native()

We can then pass pandas / PyArrow / Polars / any other supported library:

>>> my_library_agnostic_function(df_pd)
                          a
0 2024-01-01 05:45:00+05:45
1 2024-01-02 05:45:00+05:45
>>> my_library_agnostic_function(df_pl)
shape: (2, 1)
┌──────────────────────────────┐
│ a                            │
│ ---                          │
│ datetime[μs, Asia/Kathmandu] │
╞══════════════════════════════╡
│ 2024-01-01 05:45:00 +0545    │
│ 2024-01-02 05:45:00 +0545    │
└──────────────────────────────┘
>>> my_library_agnostic_function(df_pa)
pyarrow.Table
a: timestamp[us, tz=Asia/Kathmandu]
----
a: [[2024-01-01 00:00:00.000000Z,2024-01-02 00:00:00.000000Z]]

date()

Extract the date from underlying DateTime representation.

Returns:

Type Description
ExprT

A new expression.

Raises:

Type Description
NotImplementedError

If pandas default backend is being used.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {"a": [datetime(2012, 1, 7, 10, 20), datetime(2023, 3, 10, 11, 32)]}
>>> df_pd = pd.DataFrame(data).convert_dtypes(dtype_backend="pyarrow")
>>> df_pl = pl.DataFrame(data)

We define a library agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.select(nw.col("a").dt.date()).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
            a
0  2012-01-07
1  2023-03-10
>>> my_library_agnostic_function(df_pl)  # docetst
shape: (2, 1)
┌────────────┐
│ a          │
│ ---        │
│ date       │
╞════════════╡
│ 2012-01-07 │
│ 2023-03-10 │
└────────────┘

day()

Extract day from underlying DateTime representation.

Returns the day of month starting from 1. The return value ranges from 1 to 31. (The last day of month differs by months.)

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 6, 1),
...         datetime(2024, 12, 13),
...         datetime(2065, 1, 1),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.year().alias("year"),
...         nw.col("datetime").dt.month().alias("month"),
...         nw.col("datetime").dt.day().alias("day"),
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
    datetime  year  month  day
0 1978-06-01  1978      6    1
1 2024-12-13  2024     12   13
2 2065-01-01  2065      1    1
>>> my_library_agnostic_function(df_pl)
shape: (3, 4)
┌─────────────────────┬──────┬───────┬─────┐
│ datetime            ┆ year ┆ month ┆ day │
│ ---                 ┆ ---  ┆ ---   ┆ --- │
│ datetime[μs]        ┆ i32  ┆ i8    ┆ i8  │
╞═════════════════════╪══════╪═══════╪═════╡
│ 1978-06-01 00:00:00 ┆ 1978 ┆ 6     ┆ 1   │
│ 2024-12-13 00:00:00 ┆ 2024 ┆ 12    ┆ 13  │
│ 2065-01-01 00:00:00 ┆ 2065 ┆ 1     ┆ 1   │
└─────────────────────┴──────┴───────┴─────┘

hour()

Extract hour from underlying DateTime representation.

Returns the hour number from 0 to 23.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 1, 1, 1),
...         datetime(2024, 10, 13, 5),
...         datetime(2065, 1, 1, 10),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.hour().alias("hour")
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
             datetime  hour
0 1978-01-01 01:00:00     1
1 2024-10-13 05:00:00     5
2 2065-01-01 10:00:00    10
>>> my_library_agnostic_function(df_pl)
shape: (3, 2)
┌─────────────────────┬──────┐
│ datetime            ┆ hour │
│ ---                 ┆ ---  │
│ datetime[μs]        ┆ i8   │
╞═════════════════════╪══════╡
│ 1978-01-01 01:00:00 ┆ 1    │
│ 2024-10-13 05:00:00 ┆ 5    │
│ 2065-01-01 10:00:00 ┆ 10   │
└─────────────────────┴──────┘

microsecond()

Extract microseconds from underlying DateTime representation.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 1, 1, 1, 1, 1, 0),
...         datetime(2024, 10, 13, 5, 30, 14, 505000),
...         datetime(2065, 1, 1, 10, 20, 30, 67000),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.hour().alias("hour"),
...         nw.col("datetime").dt.minute().alias("minute"),
...         nw.col("datetime").dt.second().alias("second"),
...         nw.col("datetime").dt.microsecond().alias("microsecond"),
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                 datetime  hour  minute  second  microsecond
0 1978-01-01 01:01:01.000     1       1       1            0
1 2024-10-13 05:30:14.505     5      30      14       505000
2 2065-01-01 10:20:30.067    10      20      30        67000
>>> my_library_agnostic_function(df_pl)
shape: (3, 5)
┌─────────────────────────┬──────┬────────┬────────┬─────────────┐
│ datetime                ┆ hour ┆ minute ┆ second ┆ microsecond │
│ ---                     ┆ ---  ┆ ---    ┆ ---    ┆ ---         │
│ datetime[μs]            ┆ i8   ┆ i8     ┆ i8     ┆ i32         │
╞═════════════════════════╪══════╪════════╪════════╪═════════════╡
│ 1978-01-01 01:01:01     ┆ 1    ┆ 1      ┆ 1      ┆ 0           │
│ 2024-10-13 05:30:14.505 ┆ 5    ┆ 30     ┆ 14     ┆ 505000      │
│ 2065-01-01 10:20:30.067 ┆ 10   ┆ 20     ┆ 30     ┆ 67000       │
└─────────────────────────┴──────┴────────┴────────┴─────────────┘

millisecond()

Extract milliseconds from underlying DateTime representation.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 1, 1, 1, 1, 1, 0),
...         datetime(2024, 10, 13, 5, 30, 14, 505000),
...         datetime(2065, 1, 1, 10, 20, 30, 67000),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.hour().alias("hour"),
...         nw.col("datetime").dt.minute().alias("minute"),
...         nw.col("datetime").dt.second().alias("second"),
...         nw.col("datetime").dt.millisecond().alias("millisecond"),
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                 datetime  hour  minute  second  millisecond
0 1978-01-01 01:01:01.000     1       1       1            0
1 2024-10-13 05:30:14.505     5      30      14          505
2 2065-01-01 10:20:30.067    10      20      30           67
>>> my_library_agnostic_function(df_pl)
shape: (3, 5)
┌─────────────────────────┬──────┬────────┬────────┬─────────────┐
│ datetime                ┆ hour ┆ minute ┆ second ┆ millisecond │
│ ---                     ┆ ---  ┆ ---    ┆ ---    ┆ ---         │
│ datetime[μs]            ┆ i8   ┆ i8     ┆ i8     ┆ i32         │
╞═════════════════════════╪══════╪════════╪════════╪═════════════╡
│ 1978-01-01 01:01:01     ┆ 1    ┆ 1      ┆ 1      ┆ 0           │
│ 2024-10-13 05:30:14.505 ┆ 5    ┆ 30     ┆ 14     ┆ 505         │
│ 2065-01-01 10:20:30.067 ┆ 10   ┆ 20     ┆ 30     ┆ 67          │
└─────────────────────────┴──────┴────────┴────────┴─────────────┘

minute()

Extract minutes from underlying DateTime representation.

Returns the minute number from 0 to 59.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 1, 1, 1, 1),
...         datetime(2024, 10, 13, 5, 30),
...         datetime(2065, 1, 1, 10, 20),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.hour().alias("hour"),
...         nw.col("datetime").dt.minute().alias("minute"),
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
             datetime  hour  minute
0 1978-01-01 01:01:00     1       1
1 2024-10-13 05:30:00     5      30
2 2065-01-01 10:20:00    10      20
>>> my_library_agnostic_function(df_pl)
shape: (3, 3)
┌─────────────────────┬──────┬────────┐
│ datetime            ┆ hour ┆ minute │
│ ---                 ┆ ---  ┆ ---    │
│ datetime[μs]        ┆ i8   ┆ i8     │
╞═════════════════════╪══════╪════════╡
│ 1978-01-01 01:01:00 ┆ 1    ┆ 1      │
│ 2024-10-13 05:30:00 ┆ 5    ┆ 30     │
│ 2065-01-01 10:20:00 ┆ 10   ┆ 20     │
└─────────────────────┴──────┴────────┘

month()

Extract month from underlying DateTime representation.

Returns the month number starting from 1. The return value ranges from 1 to 12.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 6, 1),
...         datetime(2024, 12, 13),
...         datetime(2065, 1, 1),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.year().alias("year"),
...         nw.col("datetime").dt.month().alias("month"),
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
    datetime  year  month
0 1978-06-01  1978      6
1 2024-12-13  2024     12
2 2065-01-01  2065      1
>>> my_library_agnostic_function(df_pl)
shape: (3, 3)
┌─────────────────────┬──────┬───────┐
│ datetime            ┆ year ┆ month │
│ ---                 ┆ ---  ┆ ---   │
│ datetime[μs]        ┆ i32  ┆ i8    │
╞═════════════════════╪══════╪═══════╡
│ 1978-06-01 00:00:00 ┆ 1978 ┆ 6     │
│ 2024-12-13 00:00:00 ┆ 2024 ┆ 12    │
│ 2065-01-01 00:00:00 ┆ 2065 ┆ 1     │
└─────────────────────┴──────┴───────┘

nanosecond()

Extract Nanoseconds from underlying DateTime representation.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 1, 1, 1, 1, 1, 0),
...         datetime(2024, 10, 13, 5, 30, 14, 500000),
...         datetime(2065, 1, 1, 10, 20, 30, 60000),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.hour().alias("hour"),
...         nw.col("datetime").dt.minute().alias("minute"),
...         nw.col("datetime").dt.second().alias("second"),
...         nw.col("datetime").dt.nanosecond().alias("nanosecond"),
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                 datetime  hour  minute  second  nanosecond
0 1978-01-01 01:01:01.000     1       1       1           0
1 2024-10-13 05:30:14.500     5      30      14   500000000
2 2065-01-01 10:20:30.060    10      20      30    60000000
>>> my_library_agnostic_function(df_pl)
shape: (3, 5)
┌─────────────────────────┬──────┬────────┬────────┬────────────┐
│ datetime                ┆ hour ┆ minute ┆ second ┆ nanosecond │
│ ---                     ┆ ---  ┆ ---    ┆ ---    ┆ ---        │
│ datetime[μs]            ┆ i8   ┆ i8     ┆ i8     ┆ i32        │
╞═════════════════════════╪══════╪════════╪════════╪════════════╡
│ 1978-01-01 01:01:01     ┆ 1    ┆ 1      ┆ 1      ┆ 0          │
│ 2024-10-13 05:30:14.500 ┆ 5    ┆ 30     ┆ 14     ┆ 500000000  │
│ 2065-01-01 10:20:30.060 ┆ 10   ┆ 20     ┆ 30     ┆ 60000000   │
└─────────────────────────┴──────┴────────┴────────┴────────────┘

ordinal_day()

Get ordinal day.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {"a": [datetime(2020, 1, 1), datetime(2020, 8, 3)]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         a_ordinal_day=nw.col("a").dt.ordinal_day()
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
           a  a_ordinal_day
0 2020-01-01              1
1 2020-08-03            216
>>> my_library_agnostic_function(df_pl)
shape: (2, 2)
┌─────────────────────┬───────────────┐
│ a                   ┆ a_ordinal_day │
│ ---                 ┆ ---           │
│ datetime[μs]        ┆ i16           │
╞═════════════════════╪═══════════════╡
│ 2020-01-01 00:00:00 ┆ 1             │
│ 2020-08-03 00:00:00 ┆ 216           │
└─────────────────────┴───────────────┘

replace_time_zone(time_zone)

Replace time zone.

Parameters:

Name Type Description Default
time_zone str | None

Target time zone.

required

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> from datetime import datetime, timezone
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> data = {
...     "a": [
...         datetime(2024, 1, 1, tzinfo=timezone.utc),
...         datetime(2024, 1, 2, tzinfo=timezone.utc),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)
>>> df_pa = pa.table(data)

Let's define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.select(
...         nw.col("a").dt.replace_time_zone("Asia/Kathmandu")
...     ).to_native()

We can then pass pandas / PyArrow / Polars / any other supported library:

>>> my_library_agnostic_function(df_pd)
                          a
0 2024-01-01 00:00:00+05:45
1 2024-01-02 00:00:00+05:45
>>> my_library_agnostic_function(df_pl)
shape: (2, 1)
┌──────────────────────────────┐
│ a                            │
│ ---                          │
│ datetime[μs, Asia/Kathmandu] │
╞══════════════════════════════╡
│ 2024-01-01 00:00:00 +0545    │
│ 2024-01-02 00:00:00 +0545    │
└──────────────────────────────┘
>>> my_library_agnostic_function(df_pa)
pyarrow.Table
a: timestamp[us, tz=Asia/Kathmandu]
----
a: [[2023-12-31 18:15:00.000000Z,2024-01-01 18:15:00.000000Z]]

second()

Extract seconds from underlying DateTime representation.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 1, 1, 1, 1, 1),
...         datetime(2024, 10, 13, 5, 30, 14),
...         datetime(2065, 1, 1, 10, 20, 30),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.hour().alias("hour"),
...         nw.col("datetime").dt.minute().alias("minute"),
...         nw.col("datetime").dt.second().alias("second"),
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
             datetime  hour  minute  second
0 1978-01-01 01:01:01     1       1       1
1 2024-10-13 05:30:14     5      30      14
2 2065-01-01 10:20:30    10      20      30
>>> my_library_agnostic_function(df_pl)
shape: (3, 4)
┌─────────────────────┬──────┬────────┬────────┐
│ datetime            ┆ hour ┆ minute ┆ second │
│ ---                 ┆ ---  ┆ ---    ┆ ---    │
│ datetime[μs]        ┆ i8   ┆ i8     ┆ i8     │
╞═════════════════════╪══════╪════════╪════════╡
│ 1978-01-01 01:01:01 ┆ 1    ┆ 1      ┆ 1      │
│ 2024-10-13 05:30:14 ┆ 5    ┆ 30     ┆ 14     │
│ 2065-01-01 10:20:30 ┆ 10   ┆ 20     ┆ 30     │
└─────────────────────┴──────┴────────┴────────┘

timestamp(time_unit='us')

Return a timestamp in the given time unit.

Parameters:

Name Type Description Default
time_unit Literal['ns', 'us', 'ms']

{'ns', 'us', 'ms'} Time unit.

'us'

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> from datetime import date
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> import pandas as pd
>>> import polars as pl
>>> import pyarrow as pa
>>> data = {"date": [date(2001, 1, 1), None, date(2001, 1, 3)]}
>>> df_pd = pd.DataFrame(data, dtype="datetime64[ns]")
>>> df_pl = pl.DataFrame(data)
>>> df_pa = pa.table(data)

Let's define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("date").dt.timestamp().alias("timestamp_us"),
...         nw.col("date").dt.timestamp("ms").alias("timestamp_ms"),
...     ).to_native()

We can then pass pandas / PyArrow / Polars / any other supported library:

>>> my_library_agnostic_function(df_pd)
        date  timestamp_us  timestamp_ms
0 2001-01-01  9.783072e+14  9.783072e+11
1        NaT           NaN           NaN
2 2001-01-03  9.784800e+14  9.784800e+11
>>> my_library_agnostic_function(df_pl)
shape: (3, 3)
┌────────────┬─────────────────┬──────────────┐
│ date       ┆ timestamp_us    ┆ timestamp_ms │
│ ---        ┆ ---             ┆ ---          │
│ date       ┆ i64             ┆ i64          │
╞════════════╪═════════════════╪══════════════╡
│ 2001-01-01 ┆ 978307200000000 ┆ 978307200000 │
│ null       ┆ null            ┆ null         │
│ 2001-01-03 ┆ 978480000000000 ┆ 978480000000 │
└────────────┴─────────────────┴──────────────┘
>>> my_library_agnostic_function(df_pa)
pyarrow.Table
date: date32[day]
timestamp_us: int64
timestamp_ms: int64
----
date: [[2001-01-01,null,2001-01-03]]
timestamp_us: [[978307200000000,null,978480000000000]]
timestamp_ms: [[978307200000,null,978480000000]]

total_microseconds()

Get total microseconds.

Returns:

Type Description
ExprT

A new expression.

Notes

The function outputs the total microseconds in the int dtype by default, however, pandas may change the dtype to float when there are missing values, consider using fill_null() and cast in this case.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import timedelta
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "a": [
...         timedelta(microseconds=10),
...         timedelta(milliseconds=1, microseconds=200),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         a_total_microseconds=nw.col("a").dt.total_microseconds()
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                       a  a_total_microseconds
0 0 days 00:00:00.000010                    10
1 0 days 00:00:00.001200                  1200
>>> my_library_agnostic_function(df_pl)
shape: (2, 2)
┌──────────────┬──────────────────────┐
│ a            ┆ a_total_microseconds │
│ ---          ┆ ---                  │
│ duration[μs] ┆ i64                  │
╞══════════════╪══════════════════════╡
│ 10µs         ┆ 10                   │
│ 1200µs       ┆ 1200                 │
└──────────────┴──────────────────────┘

total_milliseconds()

Get total milliseconds.

Returns:

Type Description
ExprT

A new expression.

Notes

The function outputs the total milliseconds in the int dtype by default, however, pandas may change the dtype to float when there are missing values, consider using fill_null() and cast in this case.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import timedelta
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "a": [
...         timedelta(milliseconds=10),
...         timedelta(milliseconds=20, microseconds=40),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         a_total_milliseconds=nw.col("a").dt.total_milliseconds()
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                       a  a_total_milliseconds
0 0 days 00:00:00.010000                    10
1 0 days 00:00:00.020040                    20
>>> my_library_agnostic_function(df_pl)
shape: (2, 2)
┌──────────────┬──────────────────────┐
│ a            ┆ a_total_milliseconds │
│ ---          ┆ ---                  │
│ duration[μs] ┆ i64                  │
╞══════════════╪══════════════════════╡
│ 10ms         ┆ 10                   │
│ 20040µs      ┆ 20                   │
└──────────────┴──────────────────────┘

total_minutes()

Get total minutes.

Returns:

Type Description
ExprT

A new expression.

Notes

The function outputs the total minutes in the int dtype by default, however, pandas may change the dtype to float when there are missing values, consider using fill_null() and cast in this case.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import timedelta
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {"a": [timedelta(minutes=10), timedelta(minutes=20, seconds=40)]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         a_total_minutes=nw.col("a").dt.total_minutes()
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                a  a_total_minutes
0 0 days 00:10:00               10
1 0 days 00:20:40               20
>>> my_library_agnostic_function(df_pl)
shape: (2, 2)
┌──────────────┬─────────────────┐
│ a            ┆ a_total_minutes │
│ ---          ┆ ---             │
│ duration[μs] ┆ i64             │
╞══════════════╪═════════════════╡
│ 10m          ┆ 10              │
│ 20m 40s      ┆ 20              │
└──────────────┴─────────────────┘

total_nanoseconds()

Get total nanoseconds.

Returns:

Type Description
ExprT

A new expression.

Notes

The function outputs the total nanoseconds in the int dtype by default, however, pandas may change the dtype to float when there are missing values, consider using fill_null() and cast in this case.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import timedelta
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = ["2024-01-01 00:00:00.000000001", "2024-01-01 00:00:00.000000002"]
>>> df_pd = pd.DataFrame({"a": pd.to_datetime(data)})
>>> df_pl = pl.DataFrame({"a": data}).with_columns(
...     pl.col("a").str.to_datetime(time_unit="ns")
... )

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         a_diff_total_nanoseconds=nw.col("a").diff().dt.total_nanoseconds()
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                              a  a_diff_total_nanoseconds
0 2024-01-01 00:00:00.000000001                       NaN
1 2024-01-01 00:00:00.000000002                       1.0
>>> my_library_agnostic_function(df_pl)
shape: (2, 2)
┌───────────────────────────────┬──────────────────────────┐
│ a                             ┆ a_diff_total_nanoseconds │
│ ---                           ┆ ---                      │
│ datetime[ns]                  ┆ i64                      │
╞═══════════════════════════════╪══════════════════════════╡
│ 2024-01-01 00:00:00.000000001 ┆ null                     │
│ 2024-01-01 00:00:00.000000002 ┆ 1                        │
└───────────────────────────────┴──────────────────────────┘

total_seconds()

Get total seconds.

Returns:

Type Description
ExprT

A new expression.

Notes

The function outputs the total seconds in the int dtype by default, however, pandas may change the dtype to float when there are missing values, consider using fill_null() and cast in this case.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import timedelta
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {"a": [timedelta(seconds=10), timedelta(seconds=20, milliseconds=40)]}
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         a_total_seconds=nw.col("a").dt.total_seconds()
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                       a  a_total_seconds
0        0 days 00:00:10               10
1 0 days 00:00:20.040000               20
>>> my_library_agnostic_function(df_pl)
shape: (2, 2)
┌──────────────┬─────────────────┐
│ a            ┆ a_total_seconds │
│ ---          ┆ ---             │
│ duration[μs] ┆ i64             │
╞══════════════╪═════════════════╡
│ 10s          ┆ 10              │
│ 20s 40ms     ┆ 20              │
└──────────────┴─────────────────┘

to_string(format)

Convert a Date/Time/Datetime column into a String column with the given format.

Parameters:

Name Type Description Default
format str

Format to format temporal column with.

required

Returns:

Type Description
ExprT

A new expression.

Notes

Unfortunately, different libraries interpret format directives a bit differently.

  • Chrono, the library used by Polars, uses "%.f" for fractional seconds, whereas pandas and Python stdlib use ".%f".
  • PyArrow interprets "%S" as "seconds, including fractional seconds" whereas most other tools interpret it as "just seconds, as 2 digits".

Therefore, we make the following adjustments:

  • for pandas-like libraries, we replace "%S.%f" with "%S%.f".
  • for PyArrow, we replace "%S.%f" with "%S".

Workarounds like these don't make us happy, and we try to avoid them as much as possible, but here we feel like it's the best compromise.

If you just want to format a date/datetime Series as a local datetime string, and have it work as consistently as possible across libraries, we suggest using:

  • "%Y-%m-%dT%H:%M:%S%.f" for datetimes
  • "%Y-%m-%d" for dates

though note that, even then, different tools may return a different number of trailing zeros. Nonetheless, this is probably consistent enough for most applications.

If you have an application where this is not enough, please open an issue and let us know.

Examples:

>>> from datetime import datetime
>>> import pandas as pd
>>> import polars as pl
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = [
...     datetime(2020, 3, 1),
...     datetime(2020, 4, 1),
...     datetime(2020, 5, 1),
... ]
>>> df_pd = pd.DataFrame({"a": data})
>>> df_pl = pl.DataFrame({"a": data})

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.select(
...         nw.col("a").dt.to_string("%Y/%m/%d %H:%M:%S")
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
                     a
0  2020/03/01 00:00:00
1  2020/04/01 00:00:00
2  2020/05/01 00:00:00
>>> my_library_agnostic_function(df_pl)
shape: (3, 1)
┌─────────────────────┐
│ a                   │
│ ---                 │
│ str                 │
╞═════════════════════╡
│ 2020/03/01 00:00:00 │
│ 2020/04/01 00:00:00 │
│ 2020/05/01 00:00:00 │
└─────────────────────┘

year()

Extract year from underlying DateTime representation.

Returns the year number in the calendar date.

Returns:

Type Description
ExprT

A new expression.

Examples:

>>> import pandas as pd
>>> import polars as pl
>>> from datetime import datetime
>>> import narwhals as nw
>>> from narwhals.typing import IntoFrameT
>>> data = {
...     "datetime": [
...         datetime(1978, 6, 1),
...         datetime(2024, 12, 13),
...         datetime(2065, 1, 1),
...     ]
... }
>>> df_pd = pd.DataFrame(data)
>>> df_pl = pl.DataFrame(data)

We define a dataframe-agnostic function:

>>> def my_library_agnostic_function(df_native: IntoFrameT) -> IntoFrameT:
...     df = nw.from_native(df_native)
...     return df.with_columns(
...         nw.col("datetime").dt.year().alias("year")
...     ).to_native()

We can then pass either pandas or Polars to func:

>>> my_library_agnostic_function(df_pd)
    datetime  year
0 1978-06-01  1978
1 2024-12-13  2024
2 2065-01-01  2065
>>> my_library_agnostic_function(df_pl)
shape: (3, 2)
┌─────────────────────┬──────┐
│ datetime            ┆ year │
│ ---                 ┆ ---  │
│ datetime[μs]        ┆ i32  │
╞═════════════════════╪══════╡
│ 1978-06-01 00:00:00 ┆ 1978 │
│ 2024-12-13 00:00:00 ┆ 2024 │
│ 2065-01-01 00:00:00 ┆ 2065 │
└─────────────────────┴──────┘