ScarofScion
ScarofScion

Reputation: 1

APEX Salesforce Random days have business hours less than 24 hours

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

Upvotes: 0

Views: 776

Answers (1)

eyescream
eyescream

Reputation: 19637

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

Upvotes: 0

Related Questions