Negative Seconds with CountDown Clock?

Hey Bubblers,

I am hoping that one of you brainiacs can point out where I am going wrong with a countdown clock that I have developed using a workflow that takes a specific date in the future and counts down on a frequency that changes the closer the time gets to the future date. Everything seems to work except the seconds which instead of counting down from 59 to 0 go from 30 down to -29.

Detailed explanation

The workflow by initializing the count down measures Days, Hours, Minutes, and Seconds and based on how much time is left to count down, it sets a frequency for updating those measures.

It starts that initialization by extracting the days left in the countdown by subtracting the current date from the countdown future date and formatting that difference as days and then applies the floor function to arrive at the whole number of days left.

Then it adds the number of whole days to the current date and subtracts the resulting date (two days into the future) from the future countdown date, and formats the resulting difference as hours and applies the floor function to get the whole number of hours left.

Then it adds both the number of whole days and the number of whole hours to the current date and subtracts the result from the countdown future date and formats the resulting difference as minutes and applies the floor function to get the number of whole minutes…

It then adds the number of whole days, whole hours and whole minutes to the current date and subtracts the resulting future date from the countdown future to get the total number of seconds left in the countdown.

When I refresh the page every second, I expect this resulting initialized values for Days, Hours, Minutes and Seconds to look like the countdown but the seconds do not behave as expected. The countdown in seconds only gets as high as 30 seconds and when the second count reaches zero, the count goes into negative numbers down to -29, at which point the count starts again at positive 30.

I have tried creating the future dates based on adding Days, Hours, Minutes to the current date using +Day, +Hours +Minutes as well as adding +seconds using the Number of Whole Days * 86,400 seconds, Number of Hours * 3600 seconds but both give the unexpected negative numbers.

I have provided a detailed screenshot of each step in the workflow that relates to the initialization. The strange negative numbers occur up to step 10 in the workflow.

I have included one final shot that shows how the system changes the frequency of the countdown update as the countdown gets closer for anyone that is interested.

The attached video shows me giving a page refresh which should emulate the countdown at a frequency of about 1 second.

By my understanding of how dates and the various date functions in Bubble work, the seconds should never be less than 0.

Is this a bug or am I doing something wrong.

Cheers,

KH

Screenshots showing workflow config panels

Video of Countdown emulation by page refresh every second (or just about)

The way you are doing it looks really complicated, have you tried just updating a date custom state every second with the Current date/time, then in your text elements take the Thing's Scheduled date/time - Current date/time custom state and break it out into all the formatted days, hours, mins, seconds? A little math is involved so the overlapping units don’t include each other

1 Like

Here’s an example :blush:

Editor page

Hi Tyler,

Thanks for the help.
Your approach is definitely much more elegant than mine. Will try it out.

I actually found a video from 5 years ago from Coaching No Code Apps that uses Modulo.
They used the following formula
DD = Parent group’s date - clock’s current date/time :format as seconds / 60 / 60 / 24 modulo 365 - 0.5 :rounded to 0
I could not figure out why it was subtracting 0.5 and did not like the 365 days a year aspect as it did not allow for leap years.
Was the floor function not available back then?

While I appreciate your much more elegant solution, it is still driving me crazy that the workflow as it is currently configured gets the wacky negative seconds.
I cannot see any error in my calcs and am left wondering if I don’t understand something about the date functions that could bite me on the bum later on.
If you do see an error, please let me know.

Cheers,

KH

1 Like

It’s really hard to follow your workflows I am not sure :joy: If you are trying to keep what you have try doing debug mode and clicking on the negative value to follow where all the numbers are coming from.

Hi @kevin.hunt,

If you don’t want to be unpleasantly surprised by the Bubble bill, you should avoid refreshing the page every second. Every page load costs WU, just like every workflow that is connected to events such as “page is loaded” or “Do when page is visible”. Such workflows will fire and cost you WU every second, which is a straight route to generating enormous Bubble bills, especially if you have any searches attached to such workflows. Bubble functionality “Do every X seconds” is dedicated to making changes that are purely client-side and only for actions that will not incur any WU.

To have your desired countdown working properly and be sure that your page is loading once, you should:

  1. Put the HTML element on a page (make it 1px x 1px). Let it be visible on page load.
  2. Add inside this HTML the following JavaScript code snippet that will be responsible for counting the time left between your Quiz future date and current date. At the very bottom of the code in “startCountdown()”, insert between brackets your Quiz future date formatted as JSON-safe. The result of the code will be in the following format: (1,2,3,4,5) where: 1 = months left 2 = days left 3 = hours left 4 = minutes left 5 = seconds left Be sure that this code is visible inside this HTML element on the condition that your Quiz future date is not empty (to avoid running code without having a future date).
  3. Put the “JavaScript to Bubble” element (from Toolbox plugin) on a page (make it 1px x 1px). Let it be visible on page load. Element settings: Publish value: checked, Value type: text. In the field “bubble_fn_suffix” add the word “timer”. This element makes JS code results available for you in Bubble. So to see, for example, how many days are left, you will use the following dynamic statement in the text field: JavaScript to Bubble A value: split by (,):item #2. If you’d like to show seconds: JavaScript to Bubble A value: split by (,):item #5. Simple as that.

JS Code

<script>
// Define variables in window scope
window.globalInterval = null;
window.targetDate = null;

function startCountdown(futureDate) {
    // Clear existing interval if any
    if (window.globalInterval) {
        clearInterval(window.globalInterval);
        window.globalInterval = null;
    }

    // Updating target date
    window.targetDate = new Date(futureDate);

    // Function to calculate and display countdown
    function updateCountdown() {
        const currentDate = new Date();
        
        // If future date is in the past or equal to current date
        if (window.targetDate <= currentDate) {
            bubble_fn_timer("0,0,0,0,0");
            clearInterval(window.globalInterval);
            window.globalInterval = null;
            return;
        }

        // Calculating the difference
        const diff = window.targetDate - currentDate;

        // Calculating time components
        const months = Math.floor(diff / (1000 * 60 * 60 * 24 * 30.44));
        const days = Math.floor((diff % (1000 * 60 * 60 * 24 * 30.44)) / (1000 * 60 * 60 * 24));
        const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
        const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
        const seconds = Math.floor((diff % (1000 * 60)) / 1000);

        // Publishing the result
        bubble_fn_timer(`${months},${days},${hours},${minutes},${seconds}`);
    }

    // Run immediately
    updateCountdown();

    // Start new interval
    window.globalInterval = setInterval(updateCountdown, 1000);
}

startCountdown(HERE YOUR QUIZ FUTURE DATE FORMATED AS JSON SAFE);

</script>

Enjoy!

Tip: If you’d like to use this solution inside the RG that is showing your Quizzes list, you will need to add such a pair of elements (HTML + “JavaScript to Bubble” element) to every RG row and change “bubble_fn_suffix” from “timer” to “timer_{current cell index}” inside the HTML and in JS code. And of course, your Quiz future date.

He’s not, he’s running Do when condition is true with client-side actions, which incurs no WU cost as it’s entirely run on the browser.

1 Like

Hi @georgecollier ,

100% agree. Assuming this countdown runs once just to calculate the time difference between the current date and quiz date, then yes: there will be one page load, one client-side action, and a WU only for this page load.

Hi Marpas,
I appreciate the response.
As George pointed out, I am running the workflow client side.
I was concerned about consuming client side resources so I have configured it to step up the frequency of the count the closer I get to the deadline.

Your solution looks similar to Tyler’s and both are great.
But what I really wanto know is why I get the funky countdown I do.
Can you see anything wrong in my math/approach?

George,
I see that you have read my post. Tyler’s approach seems more elegant but I feel certain that mine should work. It is kind of driving me crazy not knowing why / how I get the funky second countdown I do?

Why try and make yours work and spend hours debugging it if you’ve found something else that’s elegant and works right now?

2 Likes

The only reason I see is that he can have more ways to approach the issue at hand

It doesn’t work because you need to use modulo since Bubble does weird rounding to math if you don’t. You can use custom states if you need the extra flexibility and don’t want to write out that expression over and over again when showing times conditionally, just put everything into a single custom event and then trigger that custom event every second like in Tyler’s example. There is not going to be any WU or overhead, this is very very simple thing for a modern computer to do, you won’t even incur any CPU % in the task manager. No need to “optimize” it.

@randomanon - thanks for this response. I thought that this must be the answer but it is great to have it confirmed.

@georgecollier - the reason I wanted to confirm this is that I don’t want to run into the issue again. I find that if I don’t lock in the essense of my error in Bubble, I repeat it more than I ought to.

@nukemanyes - thanks for the comment - in essense I want to close off approaches if it is clear that they are dead ends in Bubble - which is essentially what you were saying.

Your error was engaging in a piece of logic so complex! It’s not that there’s an error in there that’s the issue, it’s the fact you chose a long workflow with a lot of room for error vs the simple choice with very little room for error :grin:

1 Like

This topic was automatically closed after 14 days. New replies are no longer allowed.