We’re Fly.io. We run apps for our users on hardware we host around the world. Fly.io happens to be a great place to run Phoenix applications. Check out how to get started!
It turns out ChatGPT doesn’t know anything about the date or day of the week! When that’s needed for your application, how can we solve it? Fortunately, Phoenix LiveView and hooks make it easy to get the user’s timezone from the browser for localizing the date information before we give it to ChatGPT so it has the information it needs. Let’s go!
If you ask ChatGPT what day it is, it doesn’t know.
Most of the time, today’s date isn’t relevant. However, while building my personal AI Fitness Trainer, it did matter. The AI Trainer designed my weekly exercise plan and when I asked, “What is my workout today?” it hallucinated and responded, “Since today is Monday, according to your plan…” but it was Friday.
Clearly not helpful.
Sometimes we do need ChatGPT or another LLM (Large Language Model) to be date aware.
Thankfully, this is easy information for us to provide as context to a conversation when it’s relevant to our application.
Sharing date information with ChatGPT
Using the Elixir LangChain library, we can easily build prompt templates that make it easy to assemble extra information, like today’s date, into our prompts.
Remember: ChatGPT and other LLMs are text based. They specialize in being good at predicting the next text you want to see. They are not good at math or date algebra.
The key for us is to provide it with the needed date information in a good text format. Avoid giving it ambiguous dates like 10/11/23 which could be October 11th or November 10th based on a date format we didn’t provide.
Also, we can’t count on ChatGPT to arrive at the correct day of the week based on a date. Again, ChatGPT is predicting text, not running date algorithms and taking leap years into account, because, well, it doesn’t!
Thankfully, this is also easy data for us to provide! We’ll just give ChatGPT the current day of the week.
The text we’ll send to the LLM will look like this:
Today is Thursday, 2023-10-19
The date format is less ambiguous and we are also explicit about the day of the week.
The code to do this an application that uses the Elixir LangChain library looks like this:
NOTE: Using a PromptTemplate for a single statement is overkill, but it’s really helpful when we’re bringing more information together.
current_date_template = LangChain.PromptTemplate.from_template!(~S|
Today is <%= @today %>|)
LangChain.PromptTemplate.to_message!(current_date_template, %{
today: DateTime.utc_now |> Calendar.strftime("%A, %Y-%m-%d")
})
This returns a Message
struct that we’ll send to the LLM later. The Message’s contents have the following text:
"\nToday is Thursday, 2023-10-19"
Yay! When we include this text, ChatGPT knows the day and date!
Wait, the date is in the wrong timezone!
The date was generated using DateTime.utc_now/0. This means that an evening workout in my US Mountain timezone will report the date as tomorrow!
Well dang. We were so close!
In order to get the correct local date, we need to know the user’s timezone. We might be tempted to use the machine’s system clock. That works for a local development machine, but it fails when the app is deployed to a server. The machine will certainly be in the wrong timezone for most users and it may not even be setup for a timezone at all.
How can we get the timezone? We could ask the user, but that’s an annoying UX.
There is an easier way.
Let the browser tell me it’s timezone
We won’t ask the user, we’ll ask the user’s browser!
The browser knows what locale and timezone it’s running in. For applications that work best when we know the user’s timezone, then this is a handy approach with a good UX.
With LiveView, we can create a JavaScript LiveView hook that fires when the LiveView page mounts. It’s simple JavaScript that fetches the device’s timezone and pushes it to the server.
browser_timezone.js
export const hooks = {
BrowserTimezone: {
mounted() {
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone
this.pushEvent("browser-timezone", {timezone: tz})
}
}
}
We link this hook to our page in the LiveView template like this:
<main id="..." phx-hook="BrowserTimezone">
Now, when the LiveView page mounts, the hook pushes up the browser’s timezone information in a handle_event
call in the server. This is what that looks like:
def handle_event("browser-timezone", %{"timezone" => timezone}, socket) do
# do something with the timezone
{:noreply, socket}
end
At this point we do something with the timezone information. We could assign it to the LiveView socket, store it with the user’s DB record, or something else.
In the linked demo project, it is written to the DB for the user.
Great! Now the server knows the user’s timezone!
Sharing the user’s timezone based date with ChatGPT
Lastly, we’ll update the way we generate the date text sent to ChatGPT to be relative to the user’s timezone.
DateTime.now!(current_user.timezone)
Excellent!
Now our ChatGPT sessions can get the day of week and date correct every time!
Wrap up
We covered how ChatGPT doesn’t know the date and instead specializes in predicting the text we want to see. We learned how we can easily tell ChatGPT (and other LLMs) the date information it needs when it’s relevant to our application.
We also covered how to get the user’s timezone from their browser. This can be helpful for many applications that have nothing to do with ChatGPT. It’s a handy trick and LiveView + Hooks make it easy!
Show me the code!
A demo project is available with all the code discussed here:
agent_chat_live
- Directory with LiveView and template. Includes subdirectory with supporting modules.index.ex
- Agent LiveView module where events are handled and timezone is used in ChatGPT message.
browser_timezone.js
- The hook definition.app.js
- The hook is registered inapp.js
.