Salesforce公式:计算两个日期之间的营业时间

时间:2012-06-20 19:00:43

标签: salesforce

我可以使用如下公式轻松计算潜在客户的年龄:

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

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

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

想要计算工作日的数量?此公式在873个已编译的字符中执行,相比之下,Salesforce Support example here建议的模板中的1,685个(有些人抱怨{ {3}}当他们将较大的模板与其他代码合并时。)

(
    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))
)

阅读我的答案,了解它的工作原理以及如果需要,您甚至可以计算营业时间。

4 个答案:

答案 0 :(得分:5)

我通过计算两个不同日期的参考点两次的营业日来解决这个问题,然后减去它们之间的工作日数,包括小数部分,以便我可以轻松地将其转换为营业时间或营业时间。通过选择参考点作为过去星期一的业务开始,比如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个工作日的正确答案。

以下是计算营业时间内任何Salesforce记录的年龄的公式(格林尼治标准时间1300时开始的11小时):

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日之前的任何日期使用它,但是如果你选择一个更老的星期一它应该可以正常工作。

答案 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个字符。

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

答案 2 :(得分:0)

如果你可以容忍一个可重复的保证金错误

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

答案 3 :(得分:0)

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