You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Polars中计算两列时间的时间差?(跨午夜场景)

在Polars中计算跨午夜的时间差(小时)

我需要计算字符串格式的开始时间与结束时间之间的时长(以小时为单位),难点在于处理跨午夜的情况(比如23:00到24:00)。Polars原生不支持解析24:00这种时间格式,我自己写了一套处理逻辑,但感觉太复杂,想找更简洁的实现方式。

我的原始实现代码:

import polars as pl

df = pl.DataFrame(
        {
        'start_time': [
            '23:00',
            '00:00'
        ],
        'end_time': [
            '24:00',
            '01:00'
        ]
    }
)

(
    df
    .with_columns(
        start_time = pl.col('start_time').str.to_time('%H:%M'),
        end_time = pl.col('end_time').replace('24:00', '00:00').str.to_time('%H:%M')
    )
    .with_columns(
        duration = (
            pl.when(pl.col('end_time') == pl.time(0, 0, 0))
            .then(86400000000000)
            .otherwise(pl.col('end_time').cast(pl.Int64))
            - pl.col('start_time').cast(pl.Int64)) / 3600000000000
    )
)

更简洁的两种实现方式

方法1:转成当日分钟数计算

直接将时间字符串转成当日的总分钟数,处理跨午夜时只需给结束时间加1440分钟(24小时),逻辑直观易懂:

import polars as pl

df = pl.DataFrame(
    {
        'start_time': ['23:00', '00:00'],
        'end_time': ['24:00', '01:00']
    }
)

result = df.with_columns(
    # 拆分时间字符串,转成当日总分钟数
    start_minutes=pl.col('start_time').str.split(':').map_elements(
        lambda x: int(x[0])*60 + int(x[1]), 
        return_dtype=pl.Int32
    ),
    end_minutes=pl.col('end_time').str.split(':').map_elements(
        lambda x: int(x[0])*60 + int(x[1]), 
        return_dtype=pl.Int32
    )
).with_columns(
    # 跨午夜判断:结束分钟数小于开始则加1440分钟,再算差值转小时
    duration_hours=(
        pl.when(pl.col('end_minutes') < pl.col('start_minutes'))
        .then(pl.col('end_minutes') + 1440 - pl.col('start_minutes'))
        .otherwise(pl.col('end_minutes') - pl.col('start_minutes'))
    ) / 60
).drop('start_minutes', 'end_minutes')

print(result)

方法2:利用Datetime类型处理

通过给时间绑定日期,将24:00直接转成次日的00:00,再利用Polars的时间差计算功能,代码更贴合时间处理逻辑:

import polars as pl

df = pl.DataFrame(
    {
        'start_time': ['23:00', '00:00'],
        'end_time': ['24:00', '01:00']
    }
)

result = df.with_columns(
    # 将开始时间转成当日datetime
    start_dt=pl.col('start_time').str.to_datetime('%H:%M'),
    # 处理24:00:转成00:00后加1天,其他时间保持当日
    end_dt=(
        pl.col('end_time').str.replace('24:00', '00:00').str.to_datetime('%H:%M')
        + pl.when(pl.col('end_time') == '24:00').then(pl.duration(days=1)).otherwise(pl.duration(days=0))
    )
).with_columns(
    # 计算时间差并转成小时
    duration_hours=(pl.col('end_dt') - pl.col('start_dt')).dt.total_hours()
).drop('start_dt', 'end_dt')

print(result)

两种方法都能得到预期结果:

shape: (2, 3)
┌────────────┬──────────┬──────────────┐
│ start_time ┆ end_time ┆ duration_hours │
│ ---        ┆ ---      ┆ ---           │
│ str        ┆ str      ┆ f64           │
╞════════════╪══════════╪══════════════╡
│ 23:00      ┆ 24:00    ┆ 1.0           │
│ 00:00      ┆ 01:00    ┆ 1.0           │
└────────────┴──────────┴──────────────┘

内容的提问来源于stack exchange,提问作者Philipp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:59:51