我通过计算两个不同日期的参考点的营业日两次,然后减去以获得之间的营业日数(包括小数部分)来解决这个问题,这样我就可以轻松地将其转换为营业时间或营业分钟。通过将参考点选择为过去的星期一(例如 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 日之前的任何日期,但如果您选择更早的星期一,它应该可以正常工作。