How the Duration and Business Duration calculation worksIssue History: The Business Duration field was used as part of the old pre-2010 SLA engineThe Duration field is also leftover from earlier versions of the product and there are better ways of getting the information that it provides. How it works: There are a number of Business Rules that handle these operations for the various task tables. As of Calgary CCA6 here are the related Business Rules: 1) (incident) mark_resolved will set these fields when the incident_state goes to the resolved. /nav_to.do?uri=sys_script.do?sys_id=d3b21f640a0a3c7400f6acab7de3f5f8 2) (incident) mark_closed will set these fields (if not already set by the the above rule) when the incident_state goes to closed. /nav_to.do?uri=sys_script.do?sys_id=bf3f8917c0a8016400a867dc0794e8ad 3) (sc_task) Close Ticket. /nav_to.do?uri=sys_script.do?sys_id=74d38bd0c611227d0151ca6b62ae87e6 4) (change_task) Close Ticket. /nav_to.do?uri=sys_script.do?sys_id=9023ada50a0a0b01004228007704cf66 5) (problem) mark_closed. /nav_to.do?uri=sys_script.do?sys_id=12a53c4fc6112275000bc7c04a87cfb6 6) (change_request) mark_closed. /nav_to.do?uri=sys_script.do?sys_id=6e20e124c611228e00e44dd37ad1b842 calDateDiff Durations are calculated based on the closed time when an incident is closed. Not when it is resolved. This is done by the "mark_closed" business rule on the incident table, for example. The rule will also use only 1 calendar and so the duration length will be based on that calendar where the 2 days of duration would represent 48 hours of calendar time. In all cases (except "mark_closed" on change_request) these use the GlideSystem function calDateDiff current.business_duration =gs.calDateDiff(current.opened_at.getDisplayValue(), current.closed_at.getDisplayValue(), false); The calDateDiff function does not use a schedule but rather uses the calendar (System Policy -> Calendars). You only have 1 calendar which is "Monday thru Friday (9 - 5)". If there were more than 1 calendar then it would just use the first one that it finds and so it is best to change the 1 calendar to what you want. This is because calDateDiff uses the default calendar. In other words, the first record in the sys_calendar table arbitrarily returned by the database. How is business duration calculated? The calendar day values need to be verified after impersonating as the resolved_by/closed_by user as per the use case and you would be able to relate and understand how this is being calculated. The mark_resolved and mark_closed BRs uses legacy API calDateDiff which considers the first calendar from sys_calendar and calculates the duration using the user's session time zone which makes us think the calculation is wrong as we try to understand it from our perspective. Let us go through few use cases and understand how business duration is being calculated. INC0010120 opened_at: 2022-11-09 16:36:30 UTC (2022-11-09 08:36:30 London) resolved_at: 2022-11-09 16:39:38 UTC (2022-11-09 08:39:38 London) resolved_by: Gary SN resolver timezone: Europe/London calendar day: Wed 5 PM - 1 AM London business duration: 0 Reason: As the business duration would be calculated using calDateDiff function, it considers the timezone of the person who is resolving the incident and here in this case, Gary SN is from London timezone and the incident is opened (8:36:30 AM London) and resolved (8:39:38 AM London) outside the business hours 5 PM to 1 AM London. INC0010121 opened_at: 2022-11-08 16:49:47 UTC (2022-11-08 08:49:47 London) resolved_at: 2022-11-09 16:50:14 UTC (2022-11-09 08:50:14 London) resolved_by: Gary SN resolver timezone: Europe/London calendar day: Tue 5 PM - 1 AM London business duration: 8 hours calculation: As per calendar, A) from 2022-11-08 08:49:47 AM London to 2022-11-08 05:00:00 AM London, it is 0 hours B) from 2022-11-08 5:00:00 PM to 2022-11-09 1:00:00 AM, it is 8 hours C) from 2022-11-09 1:00:00 AM to 2022-11-09 08:50:14 AM, it is 0 hours So, A+B+C = 8 hours INC028853495 instance: santandertest opened_at: 2022-11-07 15:41:27 UTC (2022-11-07 16:41:27 Madrid) resolved_at: 2022-11-07 15:43:58 UTC (2022-11-07 16:43:58 Madrid) resolved_by: JORGE GARCIA AGUILAR resolver timezone: Europe/Madrid calendar day: Wed 6 PM - 2 AM Madrid business duration: 0 Reason: As the business duration would be calculated using calDateDiff function, it considers the timezone of the person who is resolving the incident and here in this case, JORGE GARCIA AGUILAR is from Europe/Madrid timezone and the incident is opened (04:41:27 PM Madrid) and resolved (04:43:58 Madrid) outside the business hours 6 PM - 2 AM Madrid. The below script can be used to verify the business duration for a given opened and resolved datetimes and it should be executed after modifying the user's time zone (who is executing this script) to the required time zone. var opened = new GlideDateTime('2022-11-07 15:41:27'); gs.info(opened.getDisplayValue()); var resolved = new GlideDateTime('2022-11-07 15:43:58'); gs.info(resolved.getDisplayValue()); gs.info(gs.calDateDiff(opened.getDisplayValue(), resolved.getDisplayValue(), false)); How business duration can be calculated according to a schedule? Any existing call to calDateDiff in the business rules ("mark_closed" and "mark_resolved") needs to be replaced with logic that calculates duration according to a schedule. Create a schedule or use an existing base system schedule.Be sure to choose the schedule time zone that is best suited to the environment: Defining a time zone, such as US/Pacific, ensures that the duration is calculated according to the schedule spans applied in the US/Pacific time zone. Copy the sys_id of the chosen schedule and modify the script for the mark_closed and mark_resolved business rules as follows: // Default Workday 8-5 Floating schedule. Replace with sys_id of the schedule to be used var schedule = new GlideSchedule("38f8b6d2c0a801640075da0e39d47696"); // Use closed_at for "mark_closed" business rule and resolved_at for "mark_resolved" business rule var duration = schedule.duration(current.opened_at.getGlideObject(), current.closed_at.getGlideObject()); // Stores value as a GlideDuration current.business_duration = duration; // Stores value in seconds. The numeric value function returns a value in milliseconds, hence divide by 1000 current.business_stc = duration.getNumericValue() / 1000;