A Flexible Countdown Timer

how to make days can be 3 digit:

136:18:46:20

The class name itself embeds how many digits you want. So if you want days to have 3 digits (including 0 padding), then you would select the day element, and adjust Class Name in the Identity Inspector from countdown_days countdown_format_1 to countdown_days countdown_format_3.

For the inner html version, you'd likewise change:

<span class="countdown_days">0</span>d

to

<span class="countdown_days countdown_format_3">0</span>d

1 Like

how to use that in your "flexible countdown timer" ?
it's look different

3 days… version of the mechanical countdown:
MechanicalLetterCountdownTimer-3days.hype.zip (74,6 KB)

2 Likes

2 posts were split to a new topic: Display problems in wedding invitation

5 posts were split to a new topic: Implementing the mechanical countdown template

@jonathan This is amazing, thank you! Question, do you have an alternative hype file of how would one use this by adding a script into resources vs using in the head of the doc?

TimerJSResources.zip (25.6 KB)

I'd imagine maybe like this? This seems work though are there better alternatives?

Yeah, I think your solution would work. You can remove this code at the end:

// use a Hype scene load handler to start:
if("HYPE_eventListeners" in window === false) {
	window.HYPE_eventListeners = Array();
}
window.HYPE_eventListeners.push({"type":"HypeSceneLoad", "callback":updateCountdownClocks});

Also it might wind up doing more work than needed if you're using multiple scenes or jump back to this scene.

The less the script code the better, I guess, but this works wonders, thank you, absolutely remarkable stuff exactly what I needed. Will show you what I got going on when it's completed.

1 Like

@jonathan Here's an example of an ad that uses your countdown method with style based on the original page design found at B&H.

All said and done, Im a bit worried it uses my machine time Eastern Time zone. Question, how do I change and limit to just EST timezone only, is there a setting in the script I can change which would, show different times as far as countdown concerned in different regions - in other words, if Im in Australia for example, I want them to see the time it begins for Australia which is 16 hours +.

Im trying to make sure the times match the EST to the rest of the world and compute regionally as far countdown is concerned, its hard to wrap my head around the time zone idea since I'm not anywhere but in EST.

Thanks in advance.

If you are setting the time and time zone in this line var countDownDateString = "2023-02-07T14:00:00-00:00"; -- it should show you the precise moment regardless of what time zone you're in. You can use this conversion tool to check: ISO8601 Date Converter Online - DenCode

The dropdown show you the time in your time zone:

Since the function determines the diff between the iso8601 string on the line: var deltaTimeInterval = targetTimeInterval - currentTimeInterval;

and the user's current computer time, it should work regardless.

Hi @Daniel,

Hope your doing well,

I had to read your response a few times to comprehend, so just to confirm, the way I have it is correct, it should compute to the time that I set within the script which is at 14:00 worldwide?

Thanks again

You would adjust this line:

countDownDateString = "2023-02-07T14:00:00-00:00"

So that it matches your 'end moment'. January 15th 9pm EST would be: 2022-01-15T21:00:00-05:00

Yes, that's what it was set to countDownDateString = "2023-02-07T14:00:00-00:00" prior my timezone paranoia :smiling_face:

Super!
Thank you for confirming.

1 Like

Looks like theres no "month" here.

what would it look like for month as far as the deltaTimeInterval field? Im trying to emulate one of the sites which has months part of the countdown.

using this `var countDownDateString = "2023-09-06T14:00:00-00:00";

function updateCountdownClocks() {
// some code from:
// How To Create a Countdown Timer
// formatting - Pad a number with leading zeros in JavaScript - Stack Overflow

var targetTimeInterval = new Date(countDownDateString).getTime();
var currentTimeInterval = new Date().getTime();

var deltaTimeInterval = targetTimeInterval - currentTimeInterval;
if(deltaTimeInterval < 0) {
	// do special handling when timer is expired; default is to just set it to 0
	deltaTimeInterval = 0;
}

var timeComponents = {
	"months" : Math.floor(deltaTimeInterval / (0 * 0 * 0 * 0)),
	"days" : Math.floor(deltaTimeInterval / (1000 * 60 * 60 * 24)),
	"hours" :  Math.floor((deltaTimeInterval % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)),
	"minutes" : Math.floor((deltaTimeInterval % (1000 * 60 * 60)) / (1000 * 60)),
	"seconds" : Math.floor((deltaTimeInterval % (1000 * 60)) / 1000),
};

// utility function to add leading 0's
function pad(n, width, z) {
	z = z || '0';
	n = n + '';
	return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
}

// utility function that gets the requested padding of zeros from a class name
// of the format countdown_format_N where 'N' is an integer for the 
// total width (ie 3 would be 088 008 888 8888)
function determinePadding(element) {
	var matches = element.className.match(/countdown\_format\_([\d]+)/);
	if(matches == null || matches.length != 2) {
		return 0;
	}
	return Math.max(0, parseInt(matches[1]));
}

// for each component, try to find a matching class name that wants to be filled in
for(var timeComponentKey in timeComponents) {
	if(timeComponents.hasOwnProperty(timeComponentKey) == false) {
		continue;
	}
	
	var timeValue = timeComponents[timeComponentKey];
	
	var timeElements = document.getElementsByClassName("countdown_" + timeComponentKey);
	for(var i = 0; i < timeElements.length; i++) {
		var timeElement = timeElements[i];
		var padding = determinePadding(timeElement);
		timeElement.innerHTML = pad(timeValue, padding);
	}
}

// repeat every second
window.setTimeout(updateCountdownClocks, 1000);

}

// start after document has loaded (without use of handlers)
window.setTimeout(updateCountdownClocks, 0);`

Looks like I got it,

"months" : Math.floor(deltaTimeInterval / (1000 * 2592000)),

thank you anyways

Using math like this is passable at the day level since most days have 24 hours, but really won't work at the month level given they can have 28-31 days.

Further, when dates are within a month, it is very ambiguous what a month means. Let's say The date is June 14 and the contest ends July 20. You're over 31 days away, but cover two partial months. So is that one month, two months, or no months since it doesn't cover a full month ever? There's lots of situations where when there's ambiguity in speech, which I would want to avoid if there's financial stakes.

Regardless if you're working with calendar dates beyond simple cases, you probably should use a calendar library that can properly handle a lot of these cases and items that are common edges like leap years/leap seconds.

I've heard moment.js is good, but I've never personally used it (there's objective-c equivalents for mac apps I have used though). There's also plugins that can do diffing between dates to give better responses. See:

It also looks like the example you sent uses a jquery plugin called "countdown"; I think this is it:

http://keith-wood.name/countdown.html

1 Like

Had a quick play with an idea of using months shown as month names rather than number.
The idea is that a month view will show the current month name with a green bar in it and the remains months plain,

Was also testing past moths being marked with a red line. but not sure that part works as expected in the way I wrote this and could actually be left out.

This coding is just me fleshing the idea out to see how practical it is to use a current month and remainder month view instead of numbers, it is not optimised and the logic would need work. I may not come back to this to do more with it but it may help ..

FlexibleCountdownTimer_months.hype.zip (65.4 KB)

1 Like

Thank you for the observation and the explanation. I wonder what does swoogo use in this scenario clearly they think it works for them, I did however bring it to the designers attention the hours were off the event starts at 9:00am 9/6/2023 however he had it completely off according to their timing in my code the event will be starting at var countDownDateString = "2023-09-04T13:00:00-00:00";?

Can you kindly check to see if whatever I'm doing here makes any sense as it relates when the even will actually occur?
Counddown.hype.zip (174.3 KB)

I wonder what would the code look like with moment .js in my example.

@MarkHunte your approach to countdown with the weeks vs months maybe the best alternative though I want to match it to style of presentation used in the example.

The code for that is in an above post.

Don't for get to add the class name countdown_weeks countdown_format_1 to the element.


On an aside I changed the line in my code from
var diff = monthDiff(currentDate, endDate) ;

var diff = monthDiff(currentDate, endDate) + 1;
Which will make sure the end month is listed.
And then added code ( not posting here since its a hacked together concept code, i.e messy) to show the remaining days in each month.

So if the date is 2023-08-10T00:00:00-00:00

or

2023-09-02T00:00:00-00:00

Any way just a thought...

1 Like