Skip to content

fix(python): Address pl.from_epoch losing fractional seconds#26419

Open
alexander-beedie wants to merge 3 commits intopola-rs:mainfrom
alexander-beedie:fix-from-epoch
Open

fix(python): Address pl.from_epoch losing fractional seconds#26419
alexander-beedie wants to merge 3 commits intopola-rs:mainfrom
alexander-beedie:fix-from-epoch

Conversation

@alexander-beedie
Copy link
Collaborator

@alexander-beedie alexander-beedie commented Feb 4, 2026

The pl.from_epoch function was forcing a cast to Int64 during calculation, despite accepting both integer and float values.

This led to lossy conversion of values with fractional seconds, as well as inconsistent rounding of seconds for negative values (dates before 1970). Results for integer input remain unchanged, but float input is now calculated correctly (also, the type signature was incomplete and has also been updated).

Example

import polars as pl
df = pl.DataFrame(
    data={
        "epoch": [
            -609066.423456,
            1066445333.8888,
            3405071999.987654,
        ],
    }
)

Before

(lossy: fractional seconds discarded/truncated)

df.with_columns(
    converted=pl.from_epoch(pl.col("epoch"), time_unit="s")
)
# shape: (3, 2)
# ┌────────────────┬─────────────────────┐
# │ epoch          ┆ converted           │
# │ ---            ┆ ---                 │
# │ f64            ┆ datetime[μs]        │
# ╞════════════════╪═════════════════════╡
# │ -609066.423456 ┆ 1969-12-24 22:48:54 │
# │ 1.0664e9       ┆ 2003-10-18 02:48:53 │
# │ 3.4051e9       ┆ 2077-11-25 13:19:59 │
# └────────────────┴─────────────────────┘

After

(fixed: fractional seconds converted/preserved)

df.with_columns(
    converted=pl.from_epoch(pl.col("epoch"), time_unit="s"),
)
# shape: (3, 2)
# ┌────────────────┬────────────────────────────┐
# │ epoch          ┆ converted                  │
# │ ---            ┆ ---                        │
# │ f64            ┆ datetime[μs]               │
# ╞════════════════╪════════════════════════════╡
# │ -609066.423456 ┆ 1969-12-24 22:48:53.576544 │
# │ 1.0664e9       ┆ 2003-10-18 02:48:53.888800 │
# │ 3.4051e9       ┆ 2077-11-25 13:19:59.987654 │
# └────────────────┴────────────────────────────┘

Note

from_epoch should probably have two unit parameters - the unit of the input and the desired unit of the output, as there's no particular reason to link input/output units given the presence of fractional seconds.

I might see if there's a backwards-compatible way to implement that in a future PR (as this one doesn't solve the related issue of fractional days being forced to Date - you might have 1.5 days and want it converted to Datetime("ms"), for example. Currently you have to scale to seconds and then convert to do this) 🤔

@alexander-beedie alexander-beedie force-pushed the fix-from-epoch branch 3 times, most recently from af04e69 to fb3751b Compare February 4, 2026 14:50
@alexander-beedie alexander-beedie changed the title fix: pl.from_epoch was lossy for fractional seconds fix(python): pl.from_epoch was lossy for fractional seconds Feb 4, 2026
@alexander-beedie alexander-beedie changed the title fix(python): pl.from_epoch was lossy for fractional seconds fix(python): Address pl.from_epoch being lossy for fractional seconds Feb 4, 2026
@alexander-beedie alexander-beedie changed the title fix(python): Address pl.from_epoch being lossy for fractional seconds fix(python): Address pl.from_epoch losing fractional seconds Feb 4, 2026
@github-actions github-actions bot added fix Bug fix python Related to Python Polars and removed title needs formatting labels Feb 4, 2026
@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.41%. Comparing base (f53ceab) to head (e0b2d65).

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #26419   +/-   ##
=======================================
  Coverage   81.40%   81.41%           
=======================================
  Files        1795     1795           
  Lines      244990   244991    +1     
  Branches     3079     3079           
=======================================
+ Hits       199443   199457   +14     
+ Misses      44761    44748   -13     
  Partials      786      786           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix Bug fix python Related to Python Polars

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments