I'm making a countdown and using a flip-clock.
Here is the markup
<div class="timer-special-offer"
data-year="#Model.SpecialOfferModel.DateStart.Value.Year"
data-month="#Model.SpecialOfferModel.DateStart.Value.Month"
data-day="#Model.SpecialOfferModel.DateStart.Value.Day"
data-hour="#Model.SpecialOfferModel.DateStart.Value.Hour"
data-minute="#Model.SpecialOfferModel.DateStart.Value.Minute"
data-second="#Model.SpecialOfferModel.DateStart.Value.Second"
data-year-now="#DateTime.Now.Year"
data-month-now="#DateTime.Now.Month"
data-day-now="#DateTime.Now.Day"
data-hour-now="#DateTime.Now.Hour"
data-minute-now="#DateTime.Now.Minute"
data-second-now="#DateTime.Now.Second">
<div class="timer-counter">
<div class="counter-inner"></div>
</div>
</div>
Js code is something like this:
$(document).ready(function () {
$('.timer-special-offer').each(function () {
var timer = $('.timer-special-offer');
if (timer.length) {
const clock = $('.counter-inner').FlipClock({
clockFace: 'DailyCounter',
countdown: true,
language: 'ru-ru'
});
const targetDate = new Date(
parseInt(timer.data('year')),
parseInt(timer.data('month')) - 1,
parseInt(timer.data('day')),
parseInt(timer.data('hour')),
parseInt(timer.data('minute')),
parseInt(timer.data('second')));
const nowDate = new Date(
parseInt(timer.data('yearNow')),
parseInt(timer.data('monthNow')) - 1,
parseInt(timer.data('dayNow')),
parseInt(timer.data('hourNow')),
parseInt(timer.data('minuteNow')),
parseInt(timer.data('secondNow')));
const time = (targetDate - nowDate) / 1000;
clock.setTime(time);
clock.start();
}
});
});
There are multiple objects with timer on them but the timer is working on the last object on the page like I never iterated through the timer-special-offer. Can't figure out why.
you are not looping on each element, your code is executing one specified code for 2..3.... times.
you have to change :
$('.timer-special-offer').each(function (index,element) {
var timer = $(element);
if (timer.length) {
const clock = timer .find('.counter-inner').FlipClock({
clockFace: 'DailyCounter',
countdown: true,
language: 'ru-ru'
});
const targetDate = new Date(
parseInt(timer.data('year')),
parseInt(timer.data('month')) - 1,
parseInt(timer.data('day')),
parseInt(timer.data('hour')),
parseInt(timer.data('minute')),
parseInt(timer.data('second')));
const nowDate = new Date(
parseInt(timer.data('yearNow')),
parseInt(timer.data('monthNow')) - 1,
parseInt(timer.data('dayNow')),
parseInt(timer.data('hourNow')),
parseInt(timer.data('minuteNow')),
parseInt(timer.data('secondNow')));
const time = (targetDate - nowDate) / 1000;
clock.setTime(time);
clock.start();
}
});
Related
I have this script. I need it to just stop at 0.
function count() {
var startTime = document.getElementById('hms').innerHTML;
var pieces = startTime.split(":");
var time = new Date();
time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms').innerHTML = newtime;
setTimeout(count, 1000);
}
count();
<div id='hms'>00:00:05</div>
Stop when string for time is '00:00:00':
function count() {
var startTime = document.getElementById('hms').innerHTML;
// exit function immediately
if(startTime==='00:00:00') return;
var pieces = startTime.split(":");
var time = new Date();
time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms').innerHTML = newtime;
setTimeout(count, 1000);
}
count();
<div id="hms">00:00:05</div>
All you need is to add a validity condition.
You can try pieces.some((value) => Number(value) > 0)
Following is a sample code:
Note I took liberty to rename variables to make it more readable.
function countDown() {
const container = document.getElementById('hms');
var startTime = container.innerHTML.trim();
var [hours, minutes, seconds] = startTime.split(":");
if ([hours, minutes, seconds].some((value) => Number(value))) {
var time = new Date();
time.setHours(hours);
time.setMinutes(minutes);
time.setSeconds(seconds);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
container.innerHTML = newtime;
setTimeout(countDown, 1000);
} else {
console.log('Ending countdown...')
}
}
countDown();
<div id='hms'>00:00:05</div>
I use final countdown to countdown timer. I provide an enddate and it works fine.
<div class="js-countdown" data-enddate="2019/1/21 15:54"></div>
my js:
var $clock = $('.js-countdown');
var d = new Date(Date.parse($clock.data("enddate").replace(/ /g, "T")));
$clock.countdown(d, function(event) {
$(this).text(
event.strftime('%D days %H:%M:%S')
);
});
</script>
It really depends on user clock, for example, when user changes time or if clock is not synced, the countdown timer doesn't work as expected.
Server time: 13:54
User time: 13:54
End date: 15:54, then countdown shows: 2(hrs):00(mins). But if:
Server time: 13:54
User time: 14:54 (it changed deliberately)
End date: 15:54, then countdown shows 1(hrs):00(mins) as I want it be 2(hrs):00(mins). How can I do change this behavior? My goal is to achieve an independent countdown timer. Would you please give me hints about that?
Edit
Here, the timer updates date. Is it reasonable to send request every time that update event fire?
I'm not sure if this is the best approach, but by now, it works fine.
var now;
var it = 1;
now = new Date(Date.parse('#DateTime.UtcNow.ToString("u")'.replace(/ /g, "T")));
setInterval(setAndSyncTime, 1000);
function setAndSyncTime() {
var t1 = new Date();
var t2 = now;
var t3 = Math.abs(t1 - t2);
if (t3 > 2000) {
if (it === 10) {
it = 0;
$.ajax({
url: '/SyncTime',
type: 'get',
success: function (response) {
now = new Date(Date.parse(response.replace(/ /g, "T")));
}
});
} else {
now = now.setSeconds(now.getSeconds() + 1);
now = new Date(now);
}
} else {
now = now.setSeconds(now.getSeconds() + 1);
now = new Date(now);
}
it++;
}
and
public virtual JsonResult SyncTime()
{
return Json(DateTime.UtcNow.ToString("u"), JsonRequestBehavior.AllowGet);
}
I'm very curious as to why my code won't run properly. I retrieve the value for the Date input from the html file and I created a function to find the difference; however, the span element will not update. Please explain to me why I'm wrong and what I could do to fix it. Thanks!
Code
const setup = () => {
let firstDate = $('#firstDate').val();
let secondDate = $('#secondDate').val();
const findTheDifferenceBetweenTwoDates = (firstDate, secondDate) => {
let timeDifference = Math.abs(secondDate.getTime() -
firstDate.getTime());
let millisecondsInADay = (1000 * 3600 * 24);
let differenceOfDays = Math.ceil(timeDifference / secondsInADay);
return differenceOfDays;
}
let result = findTheDifferenceBetweenTwoDates(firstDate, secondDate);
$("span").text(result);
}
$("span").text(result);
should be replaced with
$("#span").text(result);
if span is an id of the HTML element.
I found your problem
its not from the span, the problem is from javascript
you should parse the string date into js new Date
also you have a typo in secondsInADay should be millisecondsInADay
also there is a bug that the code will run when doc is ready
this is wrong because you are waiting input from user
so I added a submit button
check this codepin: https://codepen.io/hassanalisalem/pen/gGLyvJ
your HTML
<div class="container">
<h1>Date Difference!</h1>
<h1>First Date</h1>
<input id="firstDate" type ="date">
<br/>
<h1>Second Date</h1>
<input id="secondDate" type ="date">
<br>
<h1>Amount of Days: <span id="result"></span></h1>
<button id="submit">submit</button>
</div>
your js:
const animateBg = (i) => {
document.body.style.backgroundColor = 'hsl(' + i + ', 100%, 50%)';
setTimeout(function() {
animateBg(++i)
}, i);
}
animateBg(0);
const setup = () => {
let firstDate = $('#firstDate').val();
let secondDate = $('#secondDate').val();
const findTheDifferenceBetweenTwoDates = (firstDate, secondDate) => {
firstDate = new Date(firstDate);
secondDate = new Date(secondDate);
let timeDifference = Math.abs(secondDate.getTime() - firstDate.getTime());
let millisecondsInADay = (1000 * 3600 * 24);
let differenceOfDays = Math.ceil(timeDifference / millisecondsInADay);
return differenceOfDays;
}
let result = findTheDifferenceBetweenTwoDates(firstDate, secondDate);
alert(result);
$("#result").text(result);
}
$(document).ready(function () {
$('#submit').click(function () {
setup();
})
});
now it should work
it worked on codepen
Need to reduce the timing for the set times.
E.g. user logout time is 14:23:30 means need to show the remaining time seconds to the user.
Need to show the counter reducer time in Javascript.
Here is a timer. Like that how to reduce the time from after two minutes.
<!DOCTYPE html>
<html>
<body>
<p>A script on this page starts this clock:</p>
<p id="demo"></p>
<script>
var myVar = setInterval(myTimer, 1000);
function myTimer() {
var d = new Date();
document.getElementById("demo").innerHTML = d.toLocaleTimeString();
}
</script>
</body>
</html>
I guess this is what you are trying to get:
var initTime = new Date();
var i = 0;
function myTimer(){
i++;
var newTime = new Date(initTime.getTime() - i * 1000);
document.getElementById("demo").innerHTML = newTime.toLocaleTimeString();
}
var myVar = setInterval(myTimer, 1000);
<div id="demo"></div>
If you want to implement timer and want to calculate based on logout time.
var sampleTimer = (function() {
var today = new Date(),
logoutTime = "14:23:30".split(":"),
logoutTimeInsec = new Date(today.getFullYear(), today.getMonth(), today.getDate(), logoutTime[0], logoutTime[1], logoutTime[2]).getTime();
return function() {
var currentTime = new Date().getTime();
console.log('check');
if (logoutTimeInsec - currentTime > 0) {
setTimeout(sampleTimer, 1000);
}
}
}());
I have two count-down timers in my website. One timer would start automatically, but the next one should only start only after the 1st is completed. This should loop on forever, i.e. starting one clock after another.
Here is the code which I tried:
function count() {
var startTime = document.getElementById('hms').innerHTML;
var pieces = startTime.split(":");
var time = new Date();
time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms').innerHTML = newtime;
if (newtime !== '00:00:00') {
setTimeout(count, 1000);
} else {
count1();
}
}
count();
function count1() {
var startTime = document.getElementById('hms1').innerHTML;
var pieces = startTime.split(":");
var time = new Date();
time.setHours();
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms1').innerHTML = newtime;
if (newtime !== '00:00:00') {
setTimeout(count, 1000);
} else {
count();
}
}
HTML:
<div id="hms">00:00:10</div>
<div id="hms1">00:02:10</div>
I am unable to make this work. Help!!
Your current code is nearly there - with a couple of small issues:
time.setHours is missing a parameter on line 23, should be as follows:
var time = new Date(); time.setHours(pieces[0]);
Line 30 should call the alternate function:
setTimeout(count1, 1000);
Only one counter should be running at a time, so no need to for the last line (count1()).
Here's an updated JSBin.
However, a DRY solution here would be much more appropriate to avoid having to manage two functions:
var currentTimer = 'hms';
var alternateTimer = 'hms1';
function count() {
var timer = document.getElementById(currentTimer);
var startTime = timer.innerHTML;
var pieces = startTime.split(':');
var time = new Date();
time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(' ')[0];
// Update DOM
timer.innerHTML = newtime;
if(newtime === '00:00:00') {
// Swap the two timers
currentTimer = [alternateTimer, alternateTimer = currentTimer][0];
}
setTimeout(count, 1000);
}
count();
Hope that helps!
count should start a timeout to run count1, and the converse:
initial_count = 5; // say 5 sec. count-down
initial_count1 = 7;
ic = initial_count;
function count() {
ic--
if (ic>=0)
setTimeout(count, 1000); // refresh every 1sec.
else {
ic = initial_count1;
count1();
}
}
function count1() {
ic--
if (ic>=0)
setTimeout(count1, 1000); // refresh every 1sec.
else {
ic = initial_count;
count();
}
}
count(); // start the first alarm.
Add all the remaining of your logic...
function count() {
var startTime = document.getElementById('hms').innerHTML;
var pieces = startTime.split(":");
var time = new Date(); time.setHours(pieces[0]);
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms').innerHTML=newtime;
if(newtime!=='00:00:00'){
setTimeout(count, 1000);
}else
{
count1();
}
}
count();
function count1() {
var startTime = document.getElementById('hms1').innerHTML;
var pieces = startTime.split(":");
var time = new Date(); time.setHours();
time.setMinutes(pieces[1]);
time.setSeconds(pieces[2]);
var timedif = new Date(time.valueOf() - 1000);
var newtime = timedif.toTimeString().split(" ")[0];
document.getElementById('hms1').innerHTML=newtime;
if(newtime!=='00:00:00' && newtime!=='00:00:01' ){
setTimeout(count, 1000);
}else
{
count();
}
}
count1();