【问题标题】:Salesforce formula: Calculate business hours between two datesSalesforce 公式:计算两个日期之间的营业时间
【发布时间】:2012-06-20 19:00:43
【问题描述】:

我可以使用如下公式轻松计算潜在客户的年龄(以分钟为单位):

ROUND((NOW()-CreatedDate)*1440,0)

但是,我只想计算该时间跨度的营业时间(实际上是分钟)部分。我想在 Salesforce 公式(不是顶点触发器)中执行此操作。我找到了一些灵​​感herehere。我对这个解决方案的优先考虑:

  • Salesforce 公式低于 5,000 个字符的限制
  • 比较任意两个日期时间字段(不仅仅是 NOW() 与 CreatedDate)
  • 合理的误差范围(+/- 3 小时)
  • 忽略周末
  • 忽略太平洋时间上午 6 点至下午 5 点(格林威治标准时间 13:00-23:59)以外的时间
  • 忽略特定的假期,例如 7 月 4 日和 12 月 25 日(对我的需求来说过于复杂)

想只计算工作日数吗?这个公式用 873 个编译字符来计算,而 Salesforce 支持example here 建议的模板中的 1,685 个字符(有些人抱怨 going over the 5,000 character limit当他们将较大的模板与其他代码组合时)。

(
    5*FLOOR((TODAY()-DATE(1996,01,01))/7) + 
    MIN(5, MOD(TODAY()-DATE(1996,01,01), 7))
) - (
    5*FLOOR((DATEVALUE(CreatedDate)-DATE(1996,01,01))/7) + 
    MIN(5, MOD(DATEVALUE(CreatedDate)-DATE(1996,01,01), 7))
)

阅读我的回答,了解它是如何工作的,以及如何在需要时计算营业时间。

【问题讨论】:

    标签: salesforce


    【解决方案1】:

    我解决了这个问题,方法是从参考点计算两个不同日期的营业日两次,然后减去以获得之间的营业日数,包括小数部分,以便我可以轻松地将其转换为营业时间或营业分钟。通过将参考点选择为过去一个星期一(例如 1996 年 1 月 1 日)的营业开始,我可以使数学变得更容易,并解决 Salesforce 公式的限制。

    例如,假设我有两个日期,D1 =“5/10/2012 12:49 PM”和 D2 =“6/20/2012 14:19 PM”。我的工作周是 5 天/周 x 10 小时/天。我随意选择“2012-04-02 13:00:00”作为参考日期。从参考日期算起,到 D1 有 28.682 个工作日,到 D2 有 57.832 个工作日。减法给出了 D2 和 D1 之间 29.150 个工作日的正确答案。

    这是一个以营业时间(格林威治标准时间 1300 开始,每天 11 小时)计算任何 Salesforce 记录年龄的公式:

    ROUND(11*(
    (5*FLOOR((TODAY()-DATE(1996,01,01))/7) +
    MIN(5, 
        MOD(TODAY()-DATE(1996,01,01), 7) +
        MIN(1, 24/11*(MOD(NOW()-DATETIMEVALUE('1996-01-01 13:00:00'), 1)))
    ))
    -
    (5*FLOOR((DATEVALUE(CreatedDate)-DATE(1996,01,01))/7) +
    MIN(5, 
        MOD(DATEVALUE(CreatedDate)-DATE(1996,01,01), 7) +
        MIN(1, 24/11*(MOD(CreatedDate-DATETIMEVALUE('1996-01-01 13:00:00'), 1)))
    ))
    ), 0)
    

    让我们分解一下。我正在计算两个工作日的时间跨度。对于每一个,我都在计算完整的工作周数、最后一个部分周内的完整工作日数以及最后一个部分工作日内的部分工作时间,然后将它们全部加起来。

    (5*FLOOR((TODAY()-DATE(1996,01,01))/7)
    

    计算自参考点以来的整周数(必须是星期一),并记为每个工作日的 5 个工作日。

    MOD(TODAY()-DATE(1996,01,01), 7)
    

    计算最后部分周内额外的全天数,并计入 1 天。

    24/11*(MOD(CreatedDate-DATETIMEVALUE('1996-01-01 13:00:00'), 1))
    

    计算自营业开始以来已过去一天的部分。模数 1 只返回小数部分。乘以 24/11 会将其从 24 小时制的小数部分转换为 11 小时工作日的小数部分(对于 8 小时制的一天,可以使用 8 而不是 11)。

    MIN(1, ...)
    

    确保我们永远不会将在深夜很容易发生的零碎部分记入超过一个完整的工作日。

    MIN(5, ...)
    

    确保我们不会将在周六或周日很容易发生的部分工作周记入超过 5 个完整工作日。

    ROUND(11*(...), 0)
    

    将其从工作日转换为整个工作时间。将其保留为工作日,包括小数部分。

    结束的想法:

    • 此公式将工作假期计为工作日。我可以忍受。
    • 当我们的时间跨度与夏令时重叠时,可能会休息一小时。我可以忍受。
    • 由于我们不计算月数或年数,我认为我们不会受到闰年问题的影响。
    • 我尽可能少地使用 DATETIMEVALUE(),因为它过度夸大了公式的大小。
    • 上面的公式是 1,099 个字符,这应该让我有足够的空间为 EMEA 记录使用不同的参考日期。
    • 我不会将其用于 1996 年 1 月 1 日之前的任何日期,但如果您选择更早的星期一,它应该可以正常工作。

    【讨论】:

    • 注意,for "24/11*(MOD(CreatedDate-DATETIMEVALUE('1996-01-01 13:00:00'), 1))创业的开始。”如果 CreatedDate 在 13:00:00 之前,这部分对我不起作用。例如,如果 13:15 我得到“15 分钟”,如果 12:15 我得到“23hrs 15min”
    • 我把它改成了:24/11*(MAX(0,MOD(CreatedDate-DATETIMEVALUE(TEXT(DATEVALUE(CreatedDate))&'13:00:00'), 1)))
    【解决方案2】:

    我知道您正在寻找营业时间,但我注意到您有多个营业日公式,并认为我会在两个日期之间发布这个替代的工作日数(周一至周五):

    1 +
    (
     (EndDate__c - StartDate__c) * 5 -
     (MOD(StartDate__c - DATE(1970,1,4),7) - MOD(EndDate__c - DATE(1970,1,4),7)) * 2
    ) / 7 -
    IF(MOD(EndDate__c - DATE(1970,1,4),7) = 6,1,0) -
    IF(MOD(StartDate__c - DATE(1970,1,4),7) = 0,1,0)
    

    改编自this c# formula。编译成 479 个字符。

    理论上,您可以在此基础上计算小时数,以计算当然小时数。

    【讨论】:

      【解决方案3】:

      如果您可以容忍合理的保证金错误

      (计算自创建以来的工作日数截至日期 -1)*(11 小时)+(time_now_in_24_hr_format - 6)

      【讨论】:

      • 谢谢。如果您想尝试将其转换为公式代码,我愿意接受任何比我发布的解决方案更简单的方法。
      • (createdBy() - Today() )* (5/7) + time.hour()
      • 现在来吧——这甚至不是一个有效的公式:) 我同意(CreatedDate - NOW()) * (5/7) 通常会在正确答案的一天内出现,但它也可能会超过 30 小时。例如,(DATETIMEVALUE('2012-06-18 14:00:00') - DATETIMEVALUE('2012-06-15 22:00:00')) * (5/7) 给出 1.905,但正确答案更接近 0.3。我找不到formula equivalent for time.hour
      【解决方案4】:

      只是关于夏令时 (arrg) 的注释...当考虑到它至关重要时,我会做一个 IF 语句,如果我的源字段(例如 CreatedDate)在夏令时范围之间,我使用一个(调整)版本的公式,如果不是,我使用未调整的版本。将公式的大小加倍,但相当简单,因为这两个版本仅相差一两个字符。

      【讨论】:

        【解决方案5】:

        我知道发布这个答案已经很晚了。我最近有一个类似的要求,并且能够准备一个工作公式来获得 2dates 之间的 Total Business Minutes。如果日期之一早于工作时间,则没有负值。我在 Report 中将其用作 ROW-LEVEL 公式。 公式中使用的值: 8.5个工作小时 09:00:00 我在英国,所以 09:00:00 GMT 作为开始日。

        8.5*( (5*FLOOR((DATEVALUE(Lead.Assigned_to_First_Owner_On__c) -DATE(1996,01,01))/7) + 最小(5, MOD(DATEVALUE(Lead.Assigned_to_First_Owner_On__c)-DATE(1996,01,01), 7) + MIN(1, 24/8.5*(MAX(0,MOD(Lead.Assigned_to_First_Owner_On__c-DATETIMEVALUE(TEXT(DATEVALUE(Lead.Assigned_to_First_Owner_On__c))&'09:00:00'), 1)))) )) - (5*FLOOR((DATEVALUE(Lead.Created_Date_Full__c)-DATE(1996,01,01))/7) + 最小(5, MOD(DATEVALUE(Lead.Created_Date_Full__c)-DATE(1996,01,01), 7) + MIN(1, 24/8.5*(MAX(0,MOD(Lead.Created_Date_Full__c-DATETIMEVALUE(TEXT(DATEVALUE(Lead.Created_Date_Full__c))&'09:00:00'), 1)))) )) )*60

        希望对你有帮助

        【讨论】:

        • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-18
        • 2023-03-26
        • 2013-05-28
        • 1970-01-01
        • 1970-01-01
        • 2020-05-17
        相关资源
        最近更新 更多