Why Date Time Trips Up Agentforce Agents
To handle date time in Salesforce Agentforce correctly, the agent must know the user’s time zone, collect the date time without asking for it, and pass an unambiguous value to the action that saves the record. Miss any one of these and an Event meant for 3 PM lands at 11 AM.
The problem is easy to miss because users speak in local time (“tomorrow at 3 PM”), Salesforce stores DateTime values in UTC, and a large language model (LLM) sits in the middle. Without clear guardrails, the agent may ask “Which time zone?”, echo the offset back to the user, or send a malformed value to your Flow.
This post walks through a working Agentforce Employee Agent written in Agent Script that creates Events. It shows how the user profile context, the reasoning instructions, and the lightning__dateTimeStringType input type work together. The code is shared exactly as written, and the recommendations come at the end.
Three Building Blocks for Agentforce Time Zone Handling
The sample agent relies on three pieces. Each one removes a specific failure mode.
| Building block | What it does | Failure it prevents |
|---|---|---|
user_profile context | Makes the user’s profile details, including Time Zone, available to the agent | Asking the user for a time zone they have already set in Salesforce |
| Reasoning instructions | Tell the LLM to use the profile time zone for display and not to show it | Offsets or zone names cluttering replies |
lightning__dateTimeStringType | Types the action input as an ISO 8601 date time string that carries date, time and time zone | Free-text values (“next Friday at 3”) reaching your Flow |
According to the Lightning Types Reference, lightning__dateTimeStringType describes date, time and time zone in standard ISO 8601 format, and it is available to the Agentforce Employee agent in Lightning Experience and on mobile. That makes it the right input type for an action that creates an Event.
Agent Script adds one more advantage: it resolves a subagent’s reasoning instructions from top to bottom and applies conditional logic before the LLM reasons (Agent Script reference). The if and else in the sample uses that behavior to gate which actions the LLM can see.
Complete Agent Script Example: Event Management Agent
Here is the full Agent Script for an Agentforce Employee Agent that fetches and creates Events.
system:
instructions: |
You are an AI Agent.
messages:
welcome: |
Hi, I'm Agentforce! How can I help?
error: "Something went wrong. Try again."
config:
agent_label: "Agentforce Employee Agent"
agent_template: "EmployeeCopilot__AgentforceEmployeeAgent"
developer_name: "Agentforce_Employee_Agent"
agent_type: "AgentforceEmployeeAgent"
description: "Automate common business tasks and assist users in their flow of work."
context:
user_profile:
enabled: True
language:
default_locale: "en_US"
additional_locales:""
all_additional_locales: False
adaptive: False
variables:
currentRecordId: mutable string
description: "The Salesforce ID of the current record"
visibility: "External"
knowledge:
rag_feature_config_id: ""
citations_url: ""
citations_enabled: False
start_agent agent_router:
label: "Agent Router"
description: "Welcome the user and determine the appropriate subagent based on user input"
model_config:
model: "model://sfdc_ai__DefaultEinsteinHyperClassifier"
reasoning:
instructions: ->
| Select the best tool to call based on conversation history and user's intent.
actions:
go_to_Event_Management: @utils.transition to @subagent.Event_Management
subagent Event_Management:
label: "Event Management"
description: |
Create Events
reasoning:
instructions: ->
| The user's Time Zone value is available in the user_profile context.
| Use it for displaying Date Time values.
| Don't display the time zone value.
if @variables.currentRecordId is None:
| Ask the user to navigate to a record like Account or Opportunity to create an Event.
else:
| Use {!@actions.Fetch_Events} to fetch the Events
| Use {!@actions.Create_Event} to create the Event
actions:
Fetch_Events: @actions.Fetch_Events
with accountId = @variables.currentRecordId
available when @variables.currentRecordId is not None
Create_Event: @actions.Create_Event
with relatedWhatId = @variables.currentRecordId
with startDateTime = ...
available when @variables.currentRecordId is not None
actions:
Fetch_Events:
label: "Fetch Events"
description: |
Fetch Account Related Events
target: "flow://Agentforce_Fetch_Account_Related_Events"
inputs:
accountId: string
label: "accountId"
description: "Id of the Account"
is_required: False
outputs:
listEvents: list[object]
label: "listEvents"
description: "Events related to the Account"
complex_data_type_name: "lightning__recordInfoType"
is_displayable: False
filter_from_agent: False
Create_Event:
label: "Create Event"
description: |
Create Event record
target: "flow://Agentforce_Create_Event"
inputs:
relatedWhatId: string
label: "relatedWhatId"
description: "Parent Id of the Event record"
is_required: False
startDateTime: object
label: "startDateTime"
description: |
Start Date Time of the Event.
Do not ask the time zone.
The user's Time Zone value is available in the user_profile context.
is_required: False
complex_data_type_name: "lightning__dateTimeStringType"
outputs:
eventRecord: object
label: "eventRecord"
description: "Newly created Event record"
complex_data_type_name: "lightning__recordInfoType"
is_displayable: False
filter_from_agent: False
message: string
label: "message"
description: "Event creation notification message"
is_displayable: False
filter_from_agent: False
How the Agent Handles Date Time, Step by Step
1. Enable the user profile context
context.user_profile.enabled: True exposes the user’s profile details to the agent. This is where the Time Zone value comes from, so the agent never has to ask for it.
2. Tell the LLM how to display date time values
The Event_Management subagent opens with three instructions: the Time Zone is in the user_profile context, use it when displaying date time values, and do not display the time zone value itself. Users see “3:00 PM” and not “3:00 PM America/Toronto”, which keeps replies short.
3. Gate actions on record context
The if @variables.currentRecordId is None branch asks the user to open a record such as an Account or Opportunity. Otherwise the agent is told to use Fetch_Events and Create_Event. The available when @variables.currentRecordId is not None condition on both actions enforces the same rule in code, not just in the prompt.
4. Bind deterministic inputs, let the LLM fill the date time
In reasoning.actions, accountId and relatedWhatId are bound to @variables.currentRecordId, so the LLM never guesses an ID. startDateTime = ... leaves that one input for the LLM to fill from the conversation, which is what you want for a value the user supplies in natural language. For more on this split, see the Agent Script actions reference.
5. Type the input as an ISO 8601 date time string
The startDateTime input uses complex_data_type_name: "lightning__dateTimeStringType". Its description repeats two rules: do not ask the time zone, and read it from the user_profile context. The LLM now converts “tomorrow at 3 PM” into a structured ISO 8601 value, and the Agentforce_Create_Event Flow receives a predictable format.