Detecting an accurate current time (inc timezone) for users

Hi All,

I know this is a pretty edge case scenario and guessing there isn’t really a standardized solution for this, but wondering if there is a way to detect if the person is actually in the correct timezone of which to display the correct time for when using the expression current date time or allowing them to input times with the date/time picker.
image

For instance, I’ve had a few instances with a site that relies on a user inputting a specific time that gets miscalculated due to them having their system clock in another timezone from where they are actually located. Is there a way to work around this or detect some sort of a mismatch.

One idea is perhaps to use the built-in Current geographic position and seeing these timezones matches one another.

Another idea is possibly IP tracing, though sounds like it could prove to be unreliable at times.

Any tips or advice appreciated. Cheers

Current Date/Time is the same thing as JavaScript’s new Date(). Pinging Current Date/Time returns a date object representing the current system time.

That’s all it is and all it does.

In addition: In vanilla Bubble, Current Date/Time is the only mechanism we have to create a date object purely in an expression.

So if we want to construct a date inside of a Bubble expression, and we have no other source for a date object (e.g., an interface element like a date picker, a previously constructed date from our database, the output of some plugin that outputs a date) we will start with Current Date/Time and then, having a date object, we customize it to be the date that we need (by changing its days, years, hours, minutes, seconds, etc. parameters). In this context, it matters not whether Current Date/Time is accurate or not – we didn’t ping Current Date/Time to know what time it is, we pinged Current Date/Time just to get a date object.

Of course changing all of those parameters is kind of a pain in the butt since constructing those expressions is carpal tunnel-inducing. So one little pro tip: We actually do have another interface-less date constructor in Bubble, but it’s not obvious. If we make a custom state of type date on our page, we can give it a default value of whatever we choose. And this date will have the time parts set to zero, which can often be quite useful. Like so:

And what this does is constructs a date object that represents that date at 00:00:00 in the browser’s timezone.

I know @luke2 is familiar with this already, but for anyone wanting to understand what dates are, what I mean by “date construction” and how that’s different from “date formatting” and how timezones figure into all of this, see my video “Let’s Talk About Dates.”

Back to Current Date/Time:

It’s true that if a system clock is wrong then the date returned by Current Date/Time or new Date() will be “incorrect”. But there’s nothing we can do about that.

[Aside: Your question about, “would it be better to ping some external source for the time, if we want to be assured of an accurate alternative to Current Date/Time?” isn’t a silly one to ask. We could, in fact, write a trivial SSA to fetch a new date from the Bubble server representing “now” (we would just do new Date() and return that to the browser). We could alternatively ping some time server API and get a date that way. However, just trust that nobody does it this way. We just get the time from the browser. Practically speaking, in Bubble, the overhead involved in the API call or the trivial SSA is way too much for such a trivial operation and, by the time you get your “now” date, it will be several seconds later and that date will no longer accurately represent “now”. It would be silly to do this.]

This doesn’t have anything to do with date picking, really, as what a date picker does is constructs for us some date selected by the user. And it’s also not relevant to us if we are constructing an arbitrary date in an expression where we will rewrite all the time parts of the object (as discussed previously).

(Actually, could one problem you’re experiencing be that you are constructing dates in this way and forgetting to change the hours, minutes and seconds parts? Don’t forget to do that!)

Of course, if our use case is booking an appointment or something, then we might use Current Date/Time to represent the earliest time that a user can select. (Because it makes no sense to let the user book an appointment that occurs in the past unless your app is designed for time travelers.)

And if the system time is wildly wrong, then this could cause an issue. But literally EVERY OTHER app that user uses will suffer from the same problem and so this is not our problem and we don’t worry about it.

About Timezones, Locales and Geographic Locations:

As for the issue of establishing where the user is, this is important and is something that we care about. What we do in web apps generally is use the browser’s Locale API to understand the user’s timezone preference.

One really annoying oversight in Bubble is that, while Bubble’s date formatting interface is wonderfully complete (we can format our dates in any imaginable way and in any timezone, including dynamic values and “user’s current timezone”)… there is no vanilla way for us to read “user’s current timezone” and store it anywhere!

How stupid and annoying is that? (Really stupid and annoying.)

So, to capture that, you can use my free Browser Timezone and Locale plugin. You shouldn’t have to do this, but there you go. The timezone ID returned by Browser Timezone and Locale is exactly the same as “user’s current timezone” in date :formatted as operator. (It comes from exactly the same place.) Also, my Calendar Grid Pro plugin captures this information and exposes it as one of its states (because it would be stupid to sell you an expensive date-related plugin and then require you to install another free one to do such a basic thing! :wink:).

Again, there are edge cases where the user’s browser does not actually represent truthfully their timezone (and other locale-based preferences).

But typically it’s a good starting place. And usually we can rely on this. However, depending on your use case, you may want to confirm the user’s timezone preference.

And (again, depending on your use case) you may not want to rely at all on the browser’s reported timezone.

I know this is not your use case, @luke2, but as an example, in my vacation rental calendaring/booking app (grupz.com) – which is all about showing availability for vacation rental properties – we collect the address of the properties in question.

We do this so we can know the timezone ID where the property is located. And this is so we can display a calendar of that rental’s availability in the property’s timezone, NOT in the user’s timezone.

And, for the guest inquiry widget, the guest is selecting dates in the property’s timezone and then, when we send info about a request to the property owner, the requested dates are (again) in the property’s timezone.

So, if you desire to confirm a user’s timezone preference, you can start with the timezone ID reported by the browser. And you can present that to the user and say, “We see you’re in [timezone ID] where the local time is [Current Date/Time formatted in user’s current timezone. Is that correct?”

And if they say “yes” we are done.

If they say “no”, there are several things we can do (depending on your use case). We can acquire their location via Current Geographic Position (this will, of course trigger a browser “allow site to know your location?” warning) or we can ask for their location (by having them enter an address – note that such an address need not be specific, asking the user to enter city/country or postal code or whatever is close enough depending on your use case).

(Another pro tip: What’s the proper way to build such an address input? This sample app shows what I believe to be the best way to acquire addresses in Bubble - run mode | editor. Even if this isn’t exactly how you’d desire to do it, this sample is full of goodness that will save you a lot of thrashing!)

But in short, we need to acquire a geographic address and, from that geographic address, we can extract the timezone ID.

(Very important pro tip: Note that this consumes a Google timezone API call. And these can, after a certain level, cost real money. So, even if you’re going to store the address, also separately store the extracted timezone ID so that you don’t have to ping Google’s API every time you need that.)

Now, if your app is one used by frequent travelers or jet-setters (are these still things, one wonders? :thinking:), it is possible that they will frequently be accessing your app from different locations and so their browser-reported timezone may change a lot.

And maybe the dates they are selecting in your app should be from this current timezone or maybe they should be in the “preferred” timezone you collected earlier. And maybe you want to check that.

Well, you can do that, again, by pinging Current Geographic Position and comparing to the preference setting. If they are different and some date picking activity is important, you could pop an alert to them about that.

But (as we discussed in our private message thread about around these issues) I think the problems you are having are more about not having bothered to collect timezone previously (or perhaps incorrect construction of dates, or simply misunderstanding that dates as presented in your debug console are going to look weird compared to what your user saw, because of default formatting).

Also, I figured I’d write-up the above as it might be instructive to other Bubblers with similar questions.

7 Likes

Hey Keith,

Thank you for offering your knowledge with us! After reading many posts and seeing your video, I still struggle with one of my questions…(and feel pretty stupid because of it :frowning: )

My question is, simply put, based on which time are API Workflows running when I set a time/date?

My use case:

  • I have tasks which have to be finished on the same day (time does not matter). If the task does not get finished (i.e. a certain field gets populated) I want to run workflows on that task.
  • Therefore, I give every task that is being created a “Day-ID” which is Current Date/Time formatted as MM/DD/YYYY
  • Now I am doing an API Workflow which searches for Tasks where “Day-ID” is Current Date/Time+days (-1) formatted as MM/DD/YYYY (with some other constraints of course)
  • This finds all the tasks from yesterday that I want to be processed further
  • Ergo: This works great (for me!)

But what I am concerned about is: What if the API Workflow is considering a timezone where there is already a new day but the user sits in a timezone where it is still the same day.

Can you please shed some light on this? I have been searching the forum for hours but I am just totally lost because I always seem to find similar but not identical questions/use cases.

Thank you so much!!

Hi @Pat,

I don’t know if it helps, but according to the reference