Bubble stores all dates in UTC, but backend workflows that schedule tasks or send notifications must account for each user's local time zone. This tutorial shows you how to store user time zones, convert UTC to local time in workflow logic, and handle daylight saving transitions so your scheduled workflows fire at the right moment for every user.
Overview: Handling Time Zone Differences in Bubble Workflows
When you schedule backend workflows — such as daily reminders, recurring billing, or timed notifications — the server runs in UTC. If a user in New York expects a reminder at 9 AM EST, your workflow must calculate the correct UTC offset. This tutorial walks through capturing user time zones, storing offsets, and building workflow logic that converts times correctly even during daylight saving changes.
Prerequisites
- A Bubble app on the Growth plan or higher (backend workflows require a paid plan)
- Basic familiarity with Bubble's Workflow tab and backend workflows
- Understanding of the Data tab for creating fields
- At least one existing Data Type (User) in your app
Step-by-step guide
Add a timezone field to your User data type
Add a timezone field to your User data type
Open your Bubble editor and navigate to the Data tab. Click Data types in the sub-menu. Select the User data type. Click Create a new field. Name it timezone and set the type to text. This field will store a value like America/New_York or Europe/London. Save the field. Then create a second field called utc_offset of type number — this stores the numeric offset in hours (e.g. -5 for EST).
Pro tip: Use IANA timezone names (America/New_York) rather than abbreviations (EST) because abbreviations do not account for daylight saving time automatically.
Expected result: Your User data type now has a timezone (text) field and a utc_offset (number) field.
Detect and save the user's timezone on login
Detect and save the user's timezone on login
Go to the Design tab and open the page where users land after login. Add a workflow triggered by the Page is loaded event. Add an Only when condition: Current User's timezone is empty. As the first action, choose Plugins → Run JavaScript (requires the Toolbox plugin). In the script, enter: bubble_fn_timezone(Intl.DateTimeFormat().resolvedOptions().timeZone). Then add a second action: Account → Make changes to current user. Set timezone to the result of the JavaScript step. Set utc_offset to Current Date/Time:extract hours — Current Date/Time:formatted as custom (UTC):extract hours.
Pro tip: Install the free Toolbox plugin from the Bubble Plugin marketplace to use Run JavaScript in workflows.
Expected result: When a user loads the page and has no timezone saved, Bubble detects their browser timezone and saves it to their User record.
Create a backend workflow that schedules in local time
Create a backend workflow that schedules in local time
Navigate to the Workflow tab and click the Backend workflows link at the bottom of the Pages dropdown. Create a new backend workflow called send_local_reminder. Add two parameters: user (type User) and reminder_time (type date). In the workflow, add a Send Email action. For the scheduled time of this workflow, use the formula: reminder_time +(hours): user's utc_offset * -1. This converts the user's desired local time into UTC so the workflow fires at the correct moment.
Pro tip: Always multiply the offset by -1 when converting from local to UTC. For example, UTC-5 means you add 5 hours to get UTC.
Expected result: A backend workflow that accepts a user and a desired local time, then schedules email delivery at the corresponding UTC time.
Schedule the workflow from the frontend
Schedule the workflow from the frontend
Go back to a frontend page and create a button labeled Set Reminder. Add a workflow triggered by When Button Set Reminder is clicked. Add an action: Schedule API Workflow. Select send_local_reminder. Set user to Current User. Set reminder_time to the date/time the user selected (from a date picker on the page). Bubble will use the backend workflow's offset logic to convert the time to UTC before scheduling.
Expected result: Clicking the button schedules the backend workflow to run at the correct UTC time matching the user's local time.
Handle daylight saving time transitions
Handle daylight saving time transitions
Daylight saving changes shift UTC offsets by one hour twice a year. To handle this, create a recurring backend workflow called update_user_offsets that runs daily at midnight UTC. In this workflow, use the Schedule API Workflow on a list action targeting all users. For each user, recalculate utc_offset by comparing the current server UTC time with the user's local equivalent using their stored IANA timezone. Update the utc_offset field accordingly. This keeps offsets current even when clocks change.
Pro tip: Run the offset recalculation a few days before known DST transitions (second Sunday of March and first Sunday of November in the US) to ensure accuracy.
Expected result: User UTC offsets update automatically so scheduled workflows continue firing at the correct local time year-round.
Display dates in the user's local time zone on the frontend
Display dates in the user's local time zone on the frontend
On any page that shows dates, Bubble automatically displays them in the user's browser timezone. However, if you need to show another user's local time — for example, a meeting participant's availability — use a text element with a dynamic expression: Meeting's start_time +(hours): Meeting's host's utc_offset :formatted as hh:mm A. This converts the stored UTC time to the host's local time for display.
Expected result: Dates and times display correctly in each user's local time zone, even when viewing other users' scheduled events.
Complete working example
1TIME ZONE HANDLING — WORKFLOW SUMMARY2=====================================34DATA SETUP5 User Data Type:6 - timezone (text): e.g. "America/New_York"7 - utc_offset (number): e.g. -589FRONTEND WORKFLOW: Detect User Timezone10 Trigger: Page is loaded11 Only when: Current User's timezone is empty12 Step 1: Run JavaScript → Intl.DateTimeFormat().resolvedOptions().timeZone13 Step 2: Make changes to Current User14 - timezone = Result of step 115 - utc_offset = (local hour difference from UTC)1617BACKEND WORKFLOW: send_local_reminder18 Parameters:19 - user (User)20 - reminder_time (date)21 Schedule time calculation:22 reminder_time +(hours): user's utc_offset * -123 Step 1: Send Email to user's email24 - Subject: "Your scheduled reminder"25 - Body: dynamic content2627FRONTEND WORKFLOW: Schedule a Reminder28 Trigger: Button "Set Reminder" is clicked29 Step 1: Schedule API Workflow → send_local_reminder30 - user: Current User31 - reminder_time: DatePicker's value3233BACKEND WORKFLOW: update_user_offsets (Recurring Daily)34 Trigger: Scheduled, runs every 24 hours at 00:00 UTC35 Step 1: Search for Users (all)36 Step 2: Schedule API Workflow on a list37 - Recalculate utc_offset for each user38 - Based on IANA timezone + current DST status3940DISPLAY FORMULA (Frontend)41 Meeting time in host's zone:42 Meeting's start_time +(hours): Meeting's host's utc_offset43 :formatted as hh:mm ACommon mistakes when handling time zone differences in Bubble.io workflows: Step-by-Step Guide
Why it's a problem: Using timezone abbreviations instead of IANA names
How to avoid: Store IANA timezone identifiers like America/New_York which automatically resolve the correct offset for any date.
Why it's a problem: Forgetting that Bubble stores all dates in UTC
How to avoid: Always apply the UTC offset conversion when scheduling backend workflows: desired_local_time +(hours): utc_offset * -1.
Why it's a problem: Not updating offsets when daylight saving time changes
How to avoid: Create a recurring daily backend workflow that recalculates each user's utc_offset from their stored IANA timezone.
Why it's a problem: Performing timezone math on the frontend for server-scheduled tasks
How to avoid: Do all scheduling math in backend workflows where you control the UTC reference point.
Best practices
- Always store dates in UTC in your database and convert only for display or scheduling
- Use IANA timezone identifiers (America/New_York) instead of abbreviations (EST/EDT)
- Recalculate UTC offsets daily with a recurring backend workflow to handle DST transitions
- Test your scheduling logic with users in multiple time zones before going live
- Use Bubble's built-in date formatting for frontend display — it auto-adjusts to browser timezone
- Store the utc_offset as a number field for easy arithmetic in workflow expressions
- Log scheduled workflow times alongside the target user's timezone for debugging
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I'm building a Bubble.io app that schedules reminders for users in different time zones. How do I store each user's timezone, convert local time to UTC for backend workflow scheduling, and handle daylight saving time changes?
Add a timezone detection workflow to my app. When a user loads the dashboard, detect their browser timezone using JavaScript, save it to the User data type, and create a backend workflow that schedules emails at the user's local time by converting to UTC.
Frequently asked questions
Does Bubble store dates in UTC or the user's local time?
Bubble stores all dates in UTC on the server. On the frontend, Bubble automatically converts dates to the user's browser timezone for display. Backend workflows always operate in UTC.
How do I detect a user's timezone in Bubble?
Use the Toolbox plugin's Run JavaScript action with Intl.DateTimeFormat().resolvedOptions().timeZone. This returns the IANA timezone string (e.g., America/New_York) which you can save to a text field on the User data type.
Will my scheduled workflows break during daylight saving time changes?
Yes, if you use a static UTC offset. To prevent this, store the IANA timezone name and recalculate the numeric offset daily with a recurring backend workflow.
Can I schedule a workflow to run at 9 AM in every user's local time?
Not with a single scheduled workflow. You need to schedule individual workflows per user, each offset by their UTC difference so the workflow fires at their local 9 AM.
What is the difference between timezone and utc_offset fields?
The timezone field stores the IANA identifier (America/New_York) which never changes. The utc_offset stores the current numeric offset (-5 or -4) which changes with daylight saving time. You need both for accurate scheduling.
Can RapidDev help with complex timezone logic in my Bubble app?
Yes. RapidDev's engineering team can architect timezone-aware scheduling systems, including DST handling, multi-timezone displays, and recurring workflow optimization for apps with users worldwide.
Does the Toolbox plugin cost anything?
No. The Toolbox plugin is free and is one of the most commonly used Bubble plugins. It adds JavaScript execution, expression evaluation, and other developer utilities to your app.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation