When a dispatcher asks Agentforce Employee Agent to find gaps using phrases like "today", "as early as possible", or "ASAP", the agent might end up searching the wrong day. This happens because the agent’s internal clock is set to UTC, which may be a different calendar date than where the dispatcher actually is.
This solution fixes that by adding a simple action that reads the dispatcher’s local date and time directly from their Salesforce profile, and making sure the agent always uses that and not the UTC clock when searching for gaps.
Create the Apex class that reads the current user’s timezone from their Salesforce profile and returns the current date and time formatted in that timezone.
In Setup, search for and select Apex Classes.
Click New.
Paste the following code into the editor:
|
Apex |
|
public with sharing class GetCurrentUserDateTime { public class TimeRequest { @InvocableVariable( label='User Message' description='The user utterance that triggered this request. Pass the current user message exactly as written.' required=true) public String userMessage; } public class UserTimeResult { @InvocableVariable( label='Current Date Time' description='Current date and time in ISO 8601 format in the user local timezone, e.g. 2026-05-15T14:30:00.000+1400' required=true) public String currentDateTime; } @InvocableMethod( label='Get Current User Date Time' description='Returns the current date and time in the user local timezone. Must be called fresh for every request — the userMessage input ensures a fresh call per turn.' category='Agent' ) public static List<UserTimeResult> getCurrentTime(List<TimeRequest> requests) { List<UserTimeResult> results = new List<UserTimeResult>(); TimeZone userTZ = UserInfo.getTimeZone(); String tzId = userTZ.getID(); DateTime nowUTC = DateTime.now(); UserTimeResult result = new UserTimeResult(); result.currentDateTime = nowUTC.format('yyyy-MM-dd\'T\'HH:mm:ss.SSSZ', tzId); results.add(result); return results; } } |
Click Save.
In Setup, search for and select Apex Classes.
Click New.
Paste the following code into the editor:
|
Apex |
|
/** * @description Test class for GetCurrentUserDateTime Agentforce action. */ @IsTest private class GetCurrentUserDateTimeTest { @IsTest static void testGetCurrentTime() { GetCurrentUserDateTime.TimeRequest request = new GetCurrentUserDateTime.TimeRequest(); request.userMessage = 'find the gaps for John Smith for today'; List<GetCurrentUserDateTime.TimeRequest> requests = new List<GetCurrentUserDateTime.TimeRequest>{ request }; Test.startTest(); List<GetCurrentUserDateTime.UserTimeResult> results = GetCurrentUserDateTime.getCurrentTime(requests); Test.stopTest(); System.assertEquals(1, results.size(), 'Should return exactly one result'); GetCurrentUserDateTime.UserTimeResult result = results[0]; // Verify field is populated System.assertNotEquals(null, result.currentDateTime, 'currentDateTime should not be null'); // Verify ISO 8601 format with milliseconds (YYYY-MM-DDTHH:mm:ss.SSS±HHMM) System.assert( result.currentDateTime.contains('T'), 'currentDateTime should be in ISO 8601 format: ' + result.currentDateTime ); // Verify milliseconds separator is present System.assert( result.currentDateTime.contains('.'), 'currentDateTime should include milliseconds: ' + result.currentDateTime ); // Verify it has a timezone offset (+ or - after time) String timePart = result.currentDateTime.substringAfter('T'); System.assert( timePart.contains('+') || timePart.contains('-'), 'currentDateTime should include timezone offset: ' + result.currentDateTime ); } } |
Click Save.
Create an agent action that exposes the Apex class to the Agentforce Employee Agent.
In Setup, search for and select Agentforce Assets.
From the Actions tab, click New Agent Action.
For Reference Action Type, select Apex.
For Reference Action Category, select Invocable Method.
For Reference Action, select Get Current User Date Time (the Apex class you just created).
For Agent Action Label, enter Get Current User Date Time.
Click Next.
For Agent Action Description, enter:
"Returns the current date and time in the user local timezone. Must be called fresh for every request — the userMessage input ensures a fresh call per turn."
For Loading Text, enter Default.
Verify the inputs and outputs using the following table:
|
Name |
Description |
Notes |
|---|---|---|
|
Input: userMessage |
The user utterance that triggered this request. Pass the current user message exactly as written. |
Require input is checked. |
|
Output: currentDateTime |
Current date and time in ISO 8601 format in the user local timezone, e.g. 2026-05-15T14:30:00.000+1400 |
Show in conversation: Off Filter from agent action: Off |
When you’re done, click Finish.
Add the new action to the Field Service Dispatcher Actions subagent in the Agentforce Employee Agent.
In Setup, search for and select Agentforce Agents.
Open your Agentforce Employee Agent.
Click Open in Builder.
If the agent is active, deactivate it to make changes.
In the left panel, select the Field Service Dispatcher Actions subagent.
Click This Subagent’s Actions.
Click New and select Add from Asset Library. Search for and add the Get Current User Date Time action.
Click Finish.
Update the subagent instructions for the Field Service Dispatcher Actions subagent to ensure the agent always calls the Get Current User Date Time action before calling the Get Appointments to Fill Gaps action when the user uses a relative date phrase.
In the Agentforce Builder, select the Field Service Dispatcher Actions subagent.
Go to Instructions.
Remove the following existing instruction:
"Trigger the GetAppointmentsToFillGaps action when the user mentions searching or filling a gap. Examples of utterances to trigger this action: "find the gap", "search the gap", "fix the gap record", or similar phrases. If no specific time value is provided by the user, use the default gapStartTime value of 00:00 AM. Always call the action and do not rely on cached data from the conversation."
Add the following as the first instruction in the list: (keep the following format)
For ANY gap search request (examples: "find the gap", "search the gap", "fill the gaps", "fix the gap record", "as early as possible", "earliest", "next gap", or any similar phrasing) you MUST follow these three steps on every single turn. You are forbidden from calling GetAppointmentsToFillGaps until Step 3.
STEP 1 - Always call Get_Current_User_Date_Time first. Pass the user's current message verbatim as the userMessage input. This call is mandatory on every gap-search turn, even if you already have a date from earlier in the conversation. The system datetime header at the top of this prompt is in UTC and is FORBIDDEN as a date source. The currentDateTime output from this action is the only authoritative source for the user's local date.
STEP 2 - Before calling GetAppointmentsToFillGaps, your reasoning MUST contain these three lines exactly, with real values substituted:
baseDate = <first 10 characters of currentDateTime from Step 1, format YYYY-MM-DD>
userPhrase = "<the user's date phrase from their message, or 'none' if no phrase>"
Date parameter = <YYYY-MM-DD>
Resolution rules for the Date parameter:
- userPhrase is "tomorrow" or "next day" -> Date parameter = baseDate plus 1 day
- userPhrase is "next week" -> Date parameter = baseDate plus 7 days
- userPhrase is an explicit calendar date -> Date parameter = that date as YYYY-MM-DD
- userPhrase is "today", "now", "as early as possible", "earliest", "next gap", "any time", "soon", or "none" -> Date parameter = baseDate
- anything else -> Date parameter = baseDate
STEP 3 - Call GetAppointmentsToFillGaps with the resolved Date value from Step 2. The Date parameter is REQUIRED in every call - never omit it, never pass natural-language strings like "today" or "tomorrow", always pass a concrete YYYY-MM-DD. If gapStartTime is not provided by the user, omit it.
Click Save.
When all changes are saved, activate the agent.
In Agentforce Builder, click Activate.
Confirm the activation.
Verify that the fix is working correctly by testing the following scenarios.
Open the Agentforce Employee Agent in preview or in the Dispatcher Console.
Send the message: "Find the gaps for [Resource Name] for today"
Expected: The planner log shows Get_Current_User_Date_Time was called first, followed by GetAppointmentsToFillGaps with a Date value matching today’s date in your local timezone — not the UTC date.
In the same session, send the message for tomorrow: "Find the gaps for [Resource Name] for tomorrow"
Expected: Get_Current_User_Date_Time is called again — it is not reused from the previous turn.
Send the message: "Find the gaps for [Resource Name] as early as possible"
Expected: Get_Current_User_Date_Time is called first, and today’s local date is passed to GetAppointmentsToFillGaps.
Send the message: "Find the gaps for [Resource Name] for May 28"
Expected: Get_Current_User_Date_Time is NOT called. The agent calculates the date directly as 2026-05-28 and passes it to GetAppointmentsToFillGaps.
005386871

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.