I know there’s lots and lots and lots of threads discussing the various head-banging difficulties involved in manipulating date/time objects.
This is not an attempt to solve every single-dingle issue involved with dealing with date/times, but a lot of these discussions are about calendars and displaying dates and just wanting to be able to treat a DATE (such as "August 10, 2018) as the SAME date but in a different timezone.
Like,
"I’m trying to display a date on [insert your fave calendar solution here], but it’s not working right because the date in question was created with timezone X, but the person viewing my calendar is in timezone Y.
This would kind of be easy if I could just turn the date part in timezone X into the same date part in timezone Y, essentially throwing away the time part, but ‘transmuting’ the date into the same date in timezone Y. Why is it so hard to do that?"
So, here’s a single line of JavaScript that does just that (note: it depends on moment.js / moment-timezone scripts to do this):
Let’s say you have a Bubble date object (or a JavaScript date object). We’ll call it myDate
. Here, myDate
is July 29, 2018 at 00:00:00 in Pacific Daylight Time (that is, it indicates the start of that particular day):
console.log(myDate); // "Sun Jul 29 2018 00:00:00 GMT-0700 (Pacific Daylight Time)"
If this date is displayed in a calendar where the viewer is ALSO in PDT, they will see the date as blocked (or whatever) just fine. However, if the viewer is SOMEWHERE else, this date may show up funky, right? (Or not show up at all. Totally depends on how your calendar figures this out.)
Let’s say you want to take this date which is currently in the “America/Los Angeles” timezone ID / Pacific Daylight Time timezone and construct the same date, but in the “America/New York” timezone ID / Eastern Daylight Time timezone.
Here’s the one line of code that will do just that:
myDateInAnotherZone = moment.tz(String(moment.utc(myDate).format('YYYY-MM-DD')), 'YYYY-MM-DD', zone).toDate();
where myDate is a JavaScript date and zone is a string that represents what Bubble calls the timezone ID (and what moment calls the zone’s “name”).
In this case zone would be:
console.log(zone); // "America/New York"
The output, myDateInAnotherZone is a JavaScript date object that now looks like this:
console.log(myDateInAnotherZone); // "Sat Jul 28 2018 21:00:00 GMT-0700 (Pacific Daylight Time)"
Of course, JavaScript objects can only be shown in the browser’s timezone. So you can’t immediately see that this date is, in fact “Sun Jul 29 2018 00:00:00” in Eastern Daylight Time. But it is.
(Do it in your head: 21:00 hours in Pacific on Saturday night is in fact the first moment of Sunday morning in Eastern.)
Anyway, hooray!
So, to make this work (like in a Toolbox “Run JavaScript” workflow action or an “Expression” element), you need moment-timezone loaded. This requires moment.js AND moment-timezone, so you need to load both in an HTML element like this (both are available in cdnjs and at present these are the latest versions, but ‘duh’ this stuff changes so don’t just blindly go grabbing this code):
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js
"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.21/moment-timezone-with-data.js"></script>
Once those scripts are loaded, you can access moment-timezone like I did in the single line of code above.
BONUS BEATS:
How does this work? There’s kind of a lot going on in that one line of code, yeah?
Well, the general technique here is this:
-
You have a JavaScript date (Sun Jul 29 2018 at 00:00:00, in Pacific).
-
You turn that JavaScript date into an unambiguous text (string) version of the date. The format “YYYY-MM-DD” will suffice. (“2018-07-29”)
-
Now, you have the date as a string that is set free from the time element, timezones and all of that (important but annoying) nonsense.
-
We take that string and turn it into a moment (which is like a date but fancier). Anyway, using moment-timezone, we can construct the moment and ASSIGN IT THE TIMEZONE indicated by zone. (So now we have it’s like: Sun Jul 29 2018 00:00:00 but in Eastern Time.)
-
Now moment’s .toDate(); method is used to turn the moment back into a JavaScript date (but now that date has Eastern timezone [or whatever the string in zone represents]).
So, some variations: Let’s say you have a string date already (not a date object) like myStringDate is “2018-07-29”. The expression becomes:
myDateInAnotherZone = moment.tz(myStringDate, 'YYYY-MM-DD', zone).toDate();
This gets a little easier to understand. It’s a little more obvious that what we’re doing is telling moment, “Hey, here’s the string representation of a date. It’s formatted as YYYY-MM-DD and I want you to slap a zone on it and then turn it back into a JavaScript date. Thanks!”
The ‘YYYY-MM-DD’ part can be changed to other things of course. Like, if your date is like “07/29/2018” you could change that to ‘MM/DD/YYYY’. Moment is pretty flexible like that.
Anyway, I just wanted to leave this here in the hopes it’ll help someone.
-K-