通过


Power Query M 中的持续时间支持

Power Query M 中的持续时间表示以天、小时、分钟和秒为单位的两个时间点之间的差异。 无论是计算客户交互之间的时间、基于已用时间筛选记录还是构建基于时间的动态逻辑,持续时间对于创建可靠和智能数据模型至关重要。

本文探讨 Power Query M 中持续时间的结构、创建和作。它包括实际示例和共享提示,可帮助你有效地在自己的数据工作流中使用持续时间。

创建持续时间

持续时间由 #duration(<days>, <hours>, <minutes>, <seconds>) 函数定义。 例如, #duration(2, 3, 0, 0) 表示 2 天和 3 小时的持续时间。 Power Query M 提供了多种创建持续时间的方法,具体取决于上下文和所需的精度级别。

使用 #duration 函数

创建持续时间的最直接方法是使用 #duration(<days>, <hours>, <minutes>, <seconds>) 语法。 每个参数必须是一个数字,结果为持续时间值。

#duration(2, 5, 30, 0) // 2 days, 5 hours, 30 minutes

此函数还支持小数秒:

#duration(0, 0, 0, 1.75) // 1.75 seconds

从日期和时间值创建持续时间

还可以通过从另一个日期和时间值减去一个日期和时间值来创建持续时间。 结果是表示两者之间的时间跨度的持续时间。

let
    Source = 
    {
        #date(2025, 7, 24) - #date(2025, 7, 23),
        // Result: #duration(1, 0, 0, 0)
        #time(12, 0, 0) - #time(11, 30, 30),
        // Result: #duration(0, 0, 29, 30)
        #datetime(2025, 7, 24, 12, 0, 0) - #datetime(2025, 7, 23, 12, 0, 0),
        // Result: #duration(1, 0, 0, 0)
        #datetimezone(2025, 7, 24, 12, 0, 0, 7, 0) - #datetimezone(2025, 7, 23, 10, 30, 0, 4, 0),
        // Result: #duration(0, 22, 30, 0)
        #datetime(2025, 7, 24, 12, 0, 0) - DateTime.From(#date(2025, 7, 23))
        // Result: #duration(1, 12, 0, 0)
    }
in
    Source

注释

从不同的日期和时间类型(例如,从值中减去值date)中减去一个datetime日期和时间类型会导致错误。 如果必须使用不同的日期和时间类型来确定持续时间、使用 Date.FromDateTime.FromDateTimeZone.FromTime.From函数显式更改日期和时间类型之一。

从兼容值转换

Duration.From 函数可以将兼容的值转换为持续时间。 有关详细信息,请转到Duration.From(值)。

使用工期

在 Power Query M 中创建持续时间后,可以使用各种作和函数对其进行作。 这些功能使持续时间对于基于时间的逻辑和计算具有高度通用性。

算术运算

持续时间支持标准算术运算:

  • 加法和减法:向/减相互或从日期和时间值相加或减去持续时间。

    let
        Source = {
            #duration(1, 2, 0, 0) + #duration(0, 3, 30, 0),
            // Result: #duration(1, 5, 30, 0)
            #duration(1, 2, 0, 0) - #duration(0, 3, 30, 0),
            // Result: #duration(0, 22, 30, 0)
            #datetime(2025, 7, 24, 12, 0, 0) + #duration(0, 2, 0, 0),
            // Result: #datetime(2025, 7, 24, 14, 0, 0)
            #datetime(2025, 7, 24, 12, 0, 0) - #duration(0, 2, 0, 0),
            // Result: #datetime(2025, 7, 24, 10, 0, 0)
            #time(12, 0, 0) - #duration(0, 3, 30, 0)
            // Result: #time(8, 30, 0)
        }
    in
        Source
    
  • 求反:可以反转持续时间来反转其方向。

    let
        Source = {
            #datetime(2025, 7, 24, 12, 0, 0) + -#duration(0, 2, 0, 0),
            // Result (subtracts two hours): #datetime(2025, 7, 24, 10, 0, 0)
            #datetime(2025, 7, 23, 12, 0, 0) - #datetime(2025, 7, 24, 12, 0, 0)
            // Result: -#duration(1, 0, 0, 0)
        }
    in
        Source
    

乘法和除法

持续时间可以乘以或除以数值:

let
    Source = {
        #duration(0, 2, 0, 0) * 2,
        // Result (4 hours): #duration(0, 4, 0, 0)
        #duration(1, 0, 0, 0) / 2
        // Result (12 hours): #duration(0, 12, 0, 0)
    }
in
    Source

此计算适用于缩放持续时间或平均时间间隔。

比较

可以使用标准比较运算符比较持续时间:

let
    Source = #duration(1, 0, 0, 0) > #duration(0, 23, 59, 59)
        // Result: true
in
    Source

此计算允许在条件逻辑中使用持续时间,例如基于已用时间筛选行。

类型兼容性

持续时间与算术表达式中的日期和时间值兼容,但不能与其互换。 例如,减去两个日期和时间值会生成一个,但添加两个 duration日期和时间值无效。

let
    Source = 
    {
        #datetime(2025, 7, 24, 12, 0, 0) - #datetime(2025, 7, 23, 12, 0, 0),
        // Result: #duration(1, 0, 0, 0)
        #datetime(2025, 7, 24, 12, 0, 0) + #datetime(2025, 7, 23, 12, 0, 0)
        // Result: Error
    }
in
    Source

M 中的持续时间函数

Power Query M 包括一组内置函数,用于处理持续时间。 这些函数允许转换、提取组件和聚合持续时间值,使其成为基于时间的转换的基本工具。

Duration.From(值)

Duration.From 函数将兼容值转换为持续时间。 兼容的值包括一个数字,该数字被解释为一天中的一小部分或持续时间的文本表示形式。 转到 Duration.FromText 有关文本表示格式的信息。

let
    Source =
    {
        Duration.From(1.5),
        // Result: 1.5 days = #duration(1, 12, 0, 0)
        Duration.From("2.05:55:20.242")
        // Result: #duration(2, 5, 55, 20.242)
    }
in
    Source

组件访问器

这些函数提取持续时间的特定部分:

  • Duration.Days(<duration>)

    返回持续时间中的整天数。

  • Duration.Hours(<duration>)

    返回超过整个天数的小时数。

  • Duration.Minutes(<duration>)

    返回超过整小时数的分钟数。

  • Duration.Seconds(<duration>)

    返回超过整个分钟数的秒数。

let
    Source = #duration(2, 5, 30, 45),
    TextFormat = Text.Format(
        "Duration = #{0} days, #{1} hours, #{2} minutes, and #{3} seconds.",
        {
            Duration.Days(Source), 
            Duration.Hours(Source), 
            Duration.Minutes(Source), 
            Duration.Seconds(Source)
        }
    )
    // Results: "Duration = 2 days, 5 hours, 30 minutes, and 45 seconds."
in
    TextFormat

总值函数

这些函数返回单个单元中持续时间的总值,包括小数部分:

  • Duration.TotalDays(<duration>)
  • Duration.TotalHours(<duration>)
  • Duration.TotalMinutes(<duration>)
  • Duration.TotalSeconds(<duration>)
let
    Source = 
    {
        Duration.TotalDays(#duration(1, 12, 0, 0)),    // 1.5 days
        Duration.TotalHours(#duration(1, 12, 0, 0)),   // 36 hours
        Duration.TotalMinutes(#duration(1, 12, 0, 0)), // 2160 minutes
        Duration.TotalSeconds(#duration(1, 12, 0, 0))  // 129600 seconds
    }
in
    Source

持续时间规范化

在大多数情况下,持续时间由天数、小时(最多 23 小时)、分钟(最大 59 分钟)和秒(最大 59.9999999 秒)组成。 但是,在某些情况下,可能会超过持续时间参数中的最大值。 在这种情况下,Power Query M 会自动规范化这些值:

  • 秒溢出到分钟
  • 分钟溢出到数小时
  • 小时溢出到几天

例如,假设你有一个为正在运行的进程提供开始日期和时间的列。 此外,还有一个列,其中显示了该过程完成所花费的时间(以秒为单位)。 你想要创建第三列,该列显示进程完成的日期和时间。

let
    Source = #table(type table[StartTime = datetime, Seconds = Int64.Type],
    {
        {#datetime(2025, 7, 25, 8, 0, 0), 5400},
        {#datetime(2025, 7, 25, 13, 15, 0), 86400},
        {#datetime(2025, 7, 24, 22, 30, 0), 172800}
    }),
    AddSeconds = Table.AddColumn(
        Source, 
        "EndTime", 
        each [StartTime] + #duration(0, 0, 0, [Seconds]), 
        type datetime
    )
in
    AddSeconds

下表是这些计算的结果。

包含从开始时间和持续时间(以秒为单位)派生的结束日期和时间列的表的屏幕截图。

因此,即使只有进程发生的秒数,Power Query M 也会将持续时间值滚动到评估结果的分钟、小时和天数。

表示周、月和年

由于持续时间基于固定单位(天、小时、分钟、秒),因此没有以长度变化的周、月或年为本机概念。 duration Power Query M 中的类型是一个不考虑日历规则的固定结构。 对于跨月或几年的准确持续时间,请从另一个日期和时间中减去一个日期和时间,而不是使用固定持续时间。 此方法可以正确处理跨年、不同的月长和夏令时(DST)。 但是,另请注意,某些日期和时间行为可能会有所不同,具体取决于查询是在本地运行(在 Power Query Desktop 上)还是联机(在 Power Query Online 上)。 有关详细信息,请转到 当前日期和时间的本地、固定和 UTC 变体。 一般情况下,避免依赖长期计算的固定持续时间。