0

Business Hour Setup IMGI'm trying to calculate business hours between two days. However for some reason random days are showing up with less than 24 hours or less than 86400000 seconds in between on full day.

DateTime startDate = 2023-03-20 00:00:00; DateTime endDate = 2023-03-21 00:00:00;
BusinessHours defaultBH = [SELECT Id From BusinessHours WHERE IsDefault = true limit 1];
Long inputMillisecs =  BusinessHours.diff(defaultBH.Id, startDate, endDate);

For example the results between 2023-03-20 and 2023-03-21 is 61200000 milliseconds which is 17 hours. I have no holidays setup and business hours are Mon-Fri and 24 hours a day. I'm also seeing New Years Day and some other potential US National Holidays come up with less than 24 hours such as May 29th.

Not sure why this is happening. Anywhere else could SFDC pull hours in a day?

I expect that if I have no holidays setup and default business hours set to 24 hours Mon-Fri then every weekday should return 86400000 milliseconds. This way I can rely on the number of business hours between two days. With the following:

BusinessHours defaultBH = [SELECT Id From BusinessHours WHERE IsDefault = true limit 1];
Long inputMillisecs =  BusinessHours.diff(defaultBH.Id, startDate, endDate);

1 Answers1

0

Does DateTime startDate = 2023-03-20 00:00:00 even compile? depending on how you fix it - your date variable will be in GMT or local (your user's) timezone. https://developer.salesforce.com/docs/atlas.en-us.apexref.meta/apexref/apex_methods_system_datetime.htm

If you constructed it in GMT (for example with newInstance(date, time) - your March 20th is a Monday so midnight GMT is still ~4 pm Sunday, 8h outside of business hours.

Check if your user is in PST too and try constructing with newInstance(2023, 3, 20). Time class has getOffset() too which you could add to dates if queried from DB?

Jan 2nd and May 29th 2023 are also Mondays so same problem.

Edit

What results do you get with this?

Date d1 = Date.newInstance(2023,3,20), d2 = Date.newInstance(2023,3,21);

BusinessHours bh = [SELECT Id, TimeZoneSidKey FROM BusinessHours WHERE IsDefault = true];
System.assertEquals('America/Los_Angeles', bh.TimeZoneSidKey);

Long diff =  BusinessHours.diff(bh.Id, d1, d2); // implicit cast from Date to DateTime

System.debug('1: Do nothing, ' + diff / 1000 / 3600 + 'h'); // 17h

DateTime dt1 = d1, dt2 = d2; // Same cast but explicit
diff =  BusinessHours.diff(bh.Id, d1, d2);
System.debug('2: Explicit cast, same result so far, ' + diff / 1000 / 3600 + 'h'); // 17h
System.debug('3: Original datetime ' + dt1.formatLong());

Timezone tz = Timezone.getTimeZone(bh.TimeZoneSidKey);

Integer offset = tz.getOffset(dt1) / 1000 / 3600;

System.debug('4: Offset, ' + offset + 'h'); // 7h, at least in winter, DST
dt1 = dt1.addHours(-offset);
dt2 = dt2.addHours(-offset);

System.debug('5: Shifted datetime ' + dt1.formatLong());
diff =  BusinessHours.diff(bh.Id, dt1, dt2);
System.debug('6: shifted diff, ' + diff / 1000 / 3600 + 'h'); // 24h
eyescream
  • 18,088
  • 2
  • 34
  • 46
  • Thanks you @eyescream. I think you maybe on to the issue. I need to review the data to test this a bit, but what I'm doing is converting a Date to DateTime. The date is retrieved from Date custom fields. When I log the DateTime values I believe was returning 2023-03-20 00:00:00 and 2023-03-21 00:00:00 respectively. I'll take a look again but what you said definitely makes sense. – ScarofScion Feb 28 '23 at 22:01
  • So I can see any time I calculate the business hours between Monday and Tuesday, it spans 17 hours. – ScarofScion Mar 01 '23 at 01:42
  • Thank you eyescream. I would give you a upvote if I had enough rights. I'll make sure I can come back to do it once I do. Ultimately what I did to resolve is after realizing that any time a period spans over Sun-Mon the results would be less than2 4 hours I revised my calculations to Math.ceil as well as use a Double instead of an integer to calculate number of business days. If there's a better way to account for GMT vs PST please share. – ScarofScion Mar 09 '23 at 16:29
  • Post your own answer, even accept it and I'll happily upvote :) I'll see if I can come up with something better. – eyescream Mar 09 '23 at 20:59