Upcoming Updates to Timezone Handling in the Backend

Hey all!

We’ve been working on some improvements to how timezones are handled on the backend to improve the reliability of the “User’s Current Timezone” option, and we wanted to give the Bubble community a heads up before launching!

For reference, at the moment there are some situations where Bubble will fall back to using UTC rather than the timezone of the user that triggered the workflow. In the new implementation, “User’s Current Timezone” will always refer to the timezone of the user (or browser) that triggered a workflow and will only fall back to UTC if the HTTP request does not contain information about the timezone.

FAQ:

In what situations will this new implementation change the behavior of my app?

There’s a few small edge cases but the two big situations are:

  • When Bubble has to parse a date from a string (for example, when uploading a CSV or when reading data from the URL)

  • When using “User’s Current Timezone” in a Database Trigger

I like the current implementation! How can I keep the old behavior?

In Bubble apps, we always provide the option to set a static timezone rather than trying to detect the current user’s timezone. You can therefore change your app to work off of a static timezone of UTC, and preserve the old behavior!

When passing in a string for Bubble to parse, you can optionally specify the timezone for that string - so rather than writing “12/23/21 12:05”, you can write “12/23/21 12:05 GMT+0” to have Bubble parse the string in UTC

I have an API Workflow in which I would like to use the Current User’s Timezone. How do I create a request where Bubble can tell what timezone the request was made in?

Whenever making a request to a Bubble API, simply include an argument called “timezone_string” as part of the parameters. The value of the argument should be the name of a timezone in the TZ Database list of Time Zones

Great! When will this update come out?

We’re targeting Monday!

10 Likes

Will this impact the translation of times in the UI? The front end is automatically converting the data to the current user’s timezone, for example.

I’ve had to make sure that timezones are treated properly in a LOT of places in my app, and would love to test this before it rolls into production. Any possibility to do that?

Will this impact the translation of times in the UI? The front end is automatically converting the data to the current user’s timezone, for example.

Our testing indicates that there should be no effect to how timezones are handled in the front-end. However, please do let us know if you find any regressions!

I’ve had to make sure that timezones are treated properly in a LOT of places in my app, and would love to test this before it rolls into production. Any possibility to do that?

We do not have a mechanism for allowing users to test this kind of feature out before it rolls into production. I will however make sure to update this thread when we roll the feature out so you can verify that there are no breaking changes.

In general, assuming that no bugs sneak their way into the release, the only change you will see is that in some situations expressions that refer to “Current User’s Timezone” and were being evaluated in UTC will now be evaluated in the browser timezone - so any expressions that are already being evaluated in the browser timezone will be unaffected or that use a static or dynamic timezone will be unaffected.

Hey everyone

Just wanted to update this thread to let people know that the changes mentioned are now live!

3 Likes

@alex.stanescu

Does this work if I’m trying to schedule an API within a Bubble API using the context of the timezone parameter? For example I have a webhook that hits a Bubble API which then schedules another Bubble API in the future. I’d like that future scheduled API to run in a specific user’s timezone. Is that possible using the “timezone_string”? If it is, which API would I pass that timezone_string to?

Hey Alex!

Yes that’s certainly possible! If your original request (made by the webhook) includes the timezone_string parameter in its request, Bubble will automatically propagate that information to any API workflows scheduled using the “Schedule an API Workflow” action. The same thing applies for setting a recurring event and any data triggers that run as a result of your API call

Hope that helps!

1 Like

hi @alex.stanescu ,

I am running into an issue with timezones in database triggers and don’t really see a solution here.
So small introduction: we are building a warehouse management system to track from forecasting to actual delivery of packages. To track this we have a datatype called “channel data” which tracks the data for a specific day for a specific channel (part of a warehouse). Because this is an international application, we need to take into account timezones. Throughout the app we use a ton of “do a searches” to input/view the correct data. This has been a major lift to get this correct with all the timezone issues, but we’re pretty confident we fixed it on the frontend.

However, we are using database triggers to calculate some stuff. And as you said in this thread, the backend will use the current user’s timezone if they can. This brings a major challenge, as it is impossible to know what the timezone is that the database trigger is executed in. If I use the “current user” it doesn’t give me an option to select its “timezone”, so I can’t know what timezone it is executed in and thus I can’t take that into account in my searches, which is crucial to get the right data.
2 possible solutions:

  • Is it possible to expose the timezone the DB trigger is executed in?
  • Is it possible to choose which timezone it is trigger in (so I can manually account for it in the workflow)

Second problem which isn’t easy to solve I guess.
For a chart we use the “grouped by” functionality, for grouping by week, we can account for timezones as we just use the daily operator and sum those together. However, the grouped by month is a super nice feature to easily sum by month, but it does that grouping within the current user’s timezone. Again this results in issues in the aggregation as it takes some wrong days sometimes.

To maybe help your understanding, I will shortly explain how we create those “channel data”:

When a Channel is created, we create “Channel Data” for the coming year (365 objects) and put the date field on that day:rounded down by date. This results in 12AM, but in the current user’s timezone. If someone in CET creates the Channel Data, i.e for March 1st 12AM, that means that that specific date field is displayed to someone in CT or PT as 28 of Feb 8PM for example.
Now you can see that the round down to date operator doesn’t work in this case, as it would mistakenly show the data for March 1st to them as Feb 28.

I hope that makes things clear and I am happy to hop on a call to talk this through with you as I heard from a lot of users that timezone issues are a nightmare on Bubble.

Kind regards!

Hey @klaas.vanhoeck!

To address your first concern, we generally expose the timezone that the database trigger is executed in through options on operators that require timezone (see for instance the date formatting operator screenshot below)

In terms of choosing what timezone the trigger executes in, it will inherit whatever timezone triggered the change. In the case that the DB trigger happens because of a backend workflow that you manually ping (e.g. not through Schedule a Backend Workflow), you can manually adjust the API call to have your desired timezone (the parameter to change is timezone_string)

For your second concern, there is currently no way to fix the problem you are having. I am happy to report that we are however working on a project to improve the handling of timezones in Bubble, with features new abilities like being able to manually set the timezone of a newly created timestamp (in your case, the date field for your Channel Data), which would allow you to make everything execute in a specific timezone (say, GMT). I’ll pass along the observation that it is not possible to execute a Group By in a specific timezone to the PM assigned to this project (@grace.hong hi! this is me passing that along) and we’ll try to get that included in the final project

Hey @alex.stanescu, thanks for that juicy tidbit!

Is that documented somewhere? I searched the user manual but might have missed it.

Hi @alex.stanescu

Thanks for the quick reply.
For the first thing we found a solution today, as every user is allowed to create data in their own timezone, however, we always round it to their 12PM. Then for every search we adapt to search from +12UTC to -12UTC, and that works for now. Also the database trigger, the fact that we’re not working with “current date” but always with an already rounded date results in the wanted behaviour.

For the second problem, it is not really about setting the timezone of the date, as we can manipulate that during the creation. It is more for the operators we use, such as grouping, rounding to date etc. If it would be possible to say, group/round these based on UTC, that would be great.

:smiley:

So does this mean we will be able to properly handle floating dates?

If the new feature is like a :change timezone to operator (changing timezone but not the local time values), that would be sweet and would definitely make handling certain datetime scenarios easier. I know there’s been a feature request for this, so :crossed_fingers:. (Maybe I can do away with my Zoner plugin which currently fills this void for my own apps. :slightly_smiling_face: )

2 Likes

For the second problem, it is not really about setting the timezone of the date, as we can manipulate that during the creation. It is more for the operators we use, such as grouping, rounding to date etc. If it would be possible to say, group/round these based on UTC, that would be great.

This use case is now officially in our documentation for the project I mentioned, so if it’s feasible we’ll definitely make sure it is possible once we finish the project :slight_smile:

@sudsy

Is that documented somewhere? I searched the user manual but might have missed it.

Just submitted a documentation request to add it to the user manual! Thanks for bringing it up

So does this mean we will be able to properly handle floating dates? If the new feature is like a :change timezone to operator (changing timezone but not the local time values), that would be sweet and would definitely make handling certain datetime scenarios easier. I know there’s been a feature request for this, so :crossed_fingers:. (Maybe I can do away with my Zoner plugin which currently fills this void for my own apps. :slightly_smiling_face: )

To give some context, while we use the term date/time, a probably more accurate term for that type would be “absolute timestamp”. An absolute timestamp, which is what these all are, by definition doesn’t have a timezone associated with it (or to put it a different way, has every timezone associated with it), so a :change timezone to operator would not actually … do anything if that makes sense. As such, the project is focused more around visual clarity (making it clear that these are absolute timestamps) and more consistently enabling people to select what timezone operations are done in, and more consistently enabling people to select a timezone when interpreting arbitrary dates (so for instance, if a user types in 3/22/2022 12:00 AM, you would be able to select that you want that to be 12:00 AM EST). It is our belief that this makes a date/time type that is unmoored from absolute time (e.g. the concept of 12:00 AM) unnecessary, but we’re happy to hear if you have some use case that necessitates such a concept!

Indeed it would, and indeed it does!

Yes, that’s what I’m saying, except that I’m suggesting it could and should be possible with any Bubble date. Your example is effectively changing the timezone from the user’s current timezone (which Bubble sets by default) to a different timezone (EST in your example). I’m saying that such capability should be available for any Bubble date. (I’m using a JS date manipulation library to do it now. There are several such libraries.)

As I said, I have worked around limitations in Bubble’s timezone handling with a plugin. It enables me to convert dates to the same time but in a different timezone. Simply put, it enables “changing a timezone to” instead of “converting to a timezone” if that makes sense; and it comes in very handy in many situations.

A common example is storing birthdays. Please read this thread (I linked to a specific post, but the whole thread is worth reading) if you want to see the hoops users are being forced to jump through to perform such a simple task. That could be as simple as :change timezone to a common timezone (UTC makes most sense there).

Having a :change timezone to operator would also enable me to more easily save time-only values as Bubble date types by converting Bubble dates to a common (the same) timezone regardless of the timezone of the user who entered the value. (Think of merchants across the globe specifying their business hours.) It’s not only an efficient format to store time values, but it makes it easy to create a date range (time range, actually) and check if a particular date (time) value falls within it.

I believe I do understand how Bubble dates are stored under the hood. A timestamp is essentially just a big integer - an elapsed number of seconds (or milliseconds) since a particular reference date known as the UNIX epoch in UTC. If that’s not correct, set me straight.

I only hope that something which required a fairly simple feature to remedy is not going to be made more complicated. :grimacing:

1 Like

Hello Alex,

I have a question regarding using dates that are sent to a Server-side Actions.

Currently, all dates used in Fields of a Server-side Action default to the UTC (GMT+0),
when the date values are returned to Bubble, Bubble converts those dates back to the “User’s Current Timezone”. Is there any way to send the “User’s Current Timezone”? This is giving us problems for dates that cross the IDL (International Date Line).

Example:

  • March 17th 2022 8:00 PM (EST) = March 18th 2022 12:00 AM (UTC)
  • March 18th 2022 8:00 AM (EST) = March 18th 2022 12:00 PM (UTC)

In this example, when doing calculations Server-side, what shouldn’t be perceived as the same day for the user is referenced as the same day because of the default Timezone.

Many thanks,
Fabrice

Your example is effectively changing the timezone from the user’s current timezone (which Bubble sets by default) to a different timezone (EST in your example)

I would argue that this is not accurate – in that example, we have a textual representation of the date and we are interpreting it either in EST or in the user’s current timezone.

In general, I think this post in the thread you linked gives a good explanation of what we’re focusing on making possible (as in, they describe what isn’t currently possible).

I believe I do understand how Bubble dates are stored under the hood. A timestamp is essentially just a big integer - an elapsed number of seconds (or milliseconds) since a particular reference date known as the UNIX epoch in UTC. If that’s not correct, set me straight.

That’s 100% correct :slight_smile:

I only hope that something which required a fairly simple feature to remedy is not going to be made more complicated. :grimacing:

I can assure you that we don’t intend to make things more complicated for users!

Hey Fabrice,

Can you give me a little more context for what you’re trying to do? Are you writing a plugin and trying to parse dates in the plugin? Are you using a plugin? Are you using built-in workflow actions that occur serverside? Or are you doing something else?

Hello Alex,

Thanks for the reply. Sorry for not putting more context. Yes, I have a custom Server-Side Action from a Plugin that generates dates in the future based on a date field from the Database. I then filter out specific dates based on another date field that also comes from the Database. What I’m experiencing is the Server-Side script is interpreting all dates as UTC.

Returned values from the Server-Side Action

So in the previous example

  • Variable Last (User Data): March 17th 2022 8:35 PM (EST)
  • Variable Last (Script interpration): March 18th 2022 00:35 (UTC)
  • Variable End (User Data): March 18th 2022 8:39 AM (EST)
  • Variable End (Script interpration): March 18th 2022 12:39 (UTC)

This is generating problems when comparing 2 dates, as the Script interprets them as equal when they shouldn’t be from the User Data point of view.

Thanks for your help,
Fabrice

Understood. What Bubble does now is simply allow one to display the time represented by underlying timestamp in different timezones. The timestamp itself doesn’t change. What I’m saying is that there are times when one does want/need the ability to change the actual timestamp by “changing the timezone to” a specific timezone.

I’m coming at it from a Bubble developer’s perspective. What’s currently presented in the expression editor for any given date type is the ability to change the years, months, date, hours, minutes, and seconds to any arbitrary value; and the result is a date object with a different timestamp. All I’m saying is that it seems perfectly logical and consistent to have a similar “change timezone to” which also alters the underlying timestamp.

(What has to happen “behind the scenes” to accomplish that - such as convert to and from a textual representation of a date - is irrelevant to me as a Bubble developer. And BTW, that’s precisely what the plugin I’m using does, which simplifies date handling for me in the Bubble environment.)

Then I think we’re on the same page but approaching it from a different angle. It seems to me that just having a “change timezone to” operator would address the issue highlighted in that post and enable the handling of floating dates (as well as facilitate the use of Bubble date types as time-only values).

Of course you don’t, but there’s probably more than one way to go about it, so I guess we’ll see. Hopefully, it meets real-world needs without adding confusion or complexity. I think we’re both talking about the same thing, but we each have a different perspective on it.

Thanks for taking the time to explain. Looking forward to trying it out.

1 Like

Hi @fabrice.latour04,

I understand what you mean. The same moment in time is represented by different dates in the 2 different time zones. I think you’re on the right track by asking…

I’m not aware of a built-in Bubble way to do it (maybe someone else knows), but perhaps that’s part of the timezone handling changes planned with this announcement.

As a stopgap measure, you could probably use a JS snippet and the Toolbox plugin to pass the user’s time zone to the SSA…

Intl.DateTimeFormat().resolvedOptions().timeZone

You could then convert from UTC to the user’s local timezone in the SSA.

Just a thought.

1 Like

Hello Steve,

Thanks for giving your insight on this matter (Note: I don’t think options.timeZone is supported by IE). There’s also the Current geographic position's offset from UTC operator, but this requires that I send extra fields and if the User denies Geolocation, this fails. I just find it counterproductive and prone to errors to maintain 2 different time systems, just because the Timezone doesn’t propagate to the SSA.

Currently, I do all the operations I need in the SSA then I use the Bubble operator :filtered to ensure all dates are in the correct Timezone, as Timezones propagate in Scheduled API workflows.