I am writing a function that will help me log elapsed times between my code blocks.
function getTimestamp(date) {
let hours = date.getHours();
let minutes = date.getMinutes();
let seconds = date.getSeconds();
return `${(hours < 10 ? '0' + hours : hours)}-${(minutes < 10 ? '0' + minutes : minutes)}-${(seconds < 10 ? '0' + seconds : seconds)}`;
}
//example (wait 3 secs to see the output)
(async function(){
let d1 = new Date();
let seconds = 3;
let interval = setInterval(function(){
//console.clear();
console.log(`wait ${seconds--} seconds...`);
}, 1000);
let waitPromise = new Promise((ok,err) => {
setTimeout(function(){
ok(new Date());
}, seconds * 1000);
});
let d2 = await waitPromise;
//console.clear();
clearInterval(interval);
console.log(`Elapsed time: ${getTimestamp(new Date(d2 - d1))}`)
})();
I don't understand why my date differences are always showing 2 hours. The seconds and minutes are showing correctly, but I get a constant "2" hours together. Why is that happening ?
First of all, never use Date for time intervals. It will cause problems. Second, you should use performance.now() because it's meant for performance analysis and provides extra precision.
function getHumanReadableTime(t) {
const hours = Math.floor(t / 3600000),
minutes = Math.floor(t / 60000) % 60,
seconds = Math.floor(t / 1000) % 60;
return `${hours}-${minutes}-${seconds}`
}
(async () => {
const initialTimestamp = performance.now();
await new Promise( ok => {setTimeout(ok, 3000)});
const finalTimestamp = performance.now();
alert(getHumanReadableTime(finalTimestamp - initialTimestamp));
})()
Related
A few days ago, I created countdown timer by watching a video on YouTube. The countdown timer is completely perfect but one thing is missing from it. When the timer goes to the zero it will hide from the page.
I want to show some text when timer ends. Like if timer goes to zero then timer hides and show this message "You are too late. Stay with us".
This is a .js code in which I need some modification.
const dayDisplay = document.querySelector(".days .number");
const hourDisplay = document.querySelector(".hours .number");
const minuteDisplay = document.querySelector(".minutes .number");
const secondDisplay = document.querySelector(".seconds .number");
const countdownContainer = document.querySelector(".countdown-container");
const endDate = new Date("August 04 2020 10:38:00");
let saleEnded = false;
const updateTimer = () => {
if(countdownContainer) {
let currentDate = new Date();
let difference = endDate.getTime() - currentDate.getTime();
if (difference <= 1000) {
saleEnded = true;
}
const second = 1000;
const minute = second * 60;
const hour = minute * 60;
const day = hour * 24;
let newDay = Math.floor(difference / day);
let newHour = Math.floor((difference % day) / hour);
let newMiute = Math.floor((difference % hour) / minute);
let newSecond = Math.floor((difference % minute) / second);
dayDisplay.innerText = newDay < 10 ? "0" + newDay : newDay;
hourDisplay.innerText = newHour < 10 ? "0" + newHour : newHour;
minuteDisplay.innerText = newMiute < 10 ? "0" + newMiute : newMiute;
secondDisplay.innerText = newSecond < 10 ? "0" + newSecond : newSecond;
};
};
setInterval(() => {
if (!saleEnded) {
updateTimer();
} else {
countdownContainer.style.display = "block";
}
}, 1000);
Try this?
setInterval(() => {
if (!saleEnded) {
updateTimer();
} else {
countdownContainer.style.display = "block";
countdownContainer.innetHTML="You are too late. Stay with us";
}
}, 1000);
I'm new to angular, I would like to know if there is there a way to calculate the difference between a specific date and the current date, and then start counting the time from that difference?
Example: 29/01/2020 21:00:00 - 29/01/2020 21:30:00 gives a difference of 30 minutes ... the count should start from 30 minutes, that is 00:30:00
Demo
Code
startTime(){
this.interval = setInterval(() => {
if (this.time === 0) {
this.time++;
} else {
this.time++;
}
this.display = this.time;
return this.display;
}, 1000);
}
You could compute a difference between the two dates in milliseconds using Date.getTime(). If you create a new Date object from this difference, it will contain a representation of this interval. So you only need to increment the seconds and display the formatted time:
// difference between two dates in milliseconds
const diff = new Date('May 1,2019 11:20:00').getTime() - new Date('May 1,2019 11:00:00').getTime();
// new date object created from this difference
const start = new Date(diff);
const el = document.getElementById('time');
setInterval(() => {
// updating the time every second
start.setSeconds(start.getSeconds() + 1);
el.innerHTML = `${format(start.getUTCHours())}: ${format(start.getUTCMinutes())}: ${format(start.getUTCSeconds())}`;
}, 1000)
function format(n) {
return n < 10 ? '0' + n : '' + n;
}
<div id=time></div>
I would recommend you try moment (https://momentjs.com/docs/#/displaying/difference/).
With that you can easilly get the difference in milliseconds:
const currentTime = moment();
const someTime = moment([2010, 1, 14, 15, 25, 50, 125]) // [year, month, day, hour, minute, second, millisecond]
const millisecondDifference = currentTime.diff(someTime);
and then use that difference to set interval (or use moment/Date to transform it to something)
You don't need to use a counter, and a counter will probably not give you the result you want as setInterval/setTimeout will not fire at exactly 1000ms.
You can subtract the start date from the current date every time setInterval calls your function. then format the result:
var start = new Date('2020-01-29 21:00:00');
startTime(){
this.interval = setInterval(() => {
this.display = new Date() - start;
return this.display;
}, 1000);
}
After subtracting the current date from the given date, in milliseconds, convert it to seconds, minutes , and hours and use setInterval to update the counter.
const date = Date.parse('30 Jan 2020 01:04:56 GMT+0300'); //your given date
const elem = document.getElementById('counter')
function count() {
let countFrom = (Date.now() - date); //get the difference with the current date
//convert to seconds, minutes and hours
seconds = parseInt((countFrom/1000) % 60)
minutes = parseInt((countFrom/(1000*60)) % 60)
hours = parseInt((countFrom/(1000*60*60)) % 24);
//append `0` infront if a single digit
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
let time = `${hours}:${minutes}:${seconds}`;
elem.textContent = time;
}
setInterval(count, 1000);
<div id='counter'>00:00:00</div>
I think this solves your problem
let now = Date.now();
let future = new Date('January 29, 2020 23:59:59').getTime();
let diffInSecond = Math.floor((future - now) / 1000);
var i = diffInSecond;
var interval = setInterval(function(){
if (i == 0) clearInterval(interval);
console.log(i);
i--;
},
1000);
Everything is in second you can format the result to show something like 00:31:29
I would like to ask how is it possible to run a function every 60 seconds which has another timer inside it that only runs every 5 minutes
function systemTime() {
let currentTime = new Date();
let diem = "AM";
let h = currentTime.getHours();
let m = currentTime.getMinutes();
let s = currentTime.getSeconds();
if (h == 0) h = 12;
if (h > 12) diem = "PM";
if (h < 10) h = "0" + h;
if (m < 10) m = "0" + m;
if (s < 10) s = "0" + s;
return {
h: h.toString(),
m: m.toString(),
diem: diem
}
}
async function serverTime() {
let timeUrl = 'https://worldtimeapi.org/api/timezone/Europe';
let response = await fetch(timeUrl);
let data = await response.json();
let timestamp = data.datetime;
let time = timestamp.split('T')[1].split('.')[0];
let timeArray = time.split(':');
if(parseInt(timeArray[0]) > 12) timeArray[2] = 'PM'
else timeArray[2] = 'AM';
return {
h: timeArray[0],
m: timeArray[1],
diem: timeArray[2]
}
}
async function clock() {
let h, m, diem;
let container = document.querySelector('#displayClock');
container.innerHTML = `${h} : ${m}`;
setInterval(() => clock(), 60000);
// I would like to grab the server time every 5 min for comparison
setInterval(() => {}, 60000*5) // set minutes and hours to the server time
}
I would like to call the clock() function every 60s to display the time on a page but at the same time I would like to call the serverTime() function every 5 minutes to compare the values and take the serverTime if they are not the same.
Calling clock() every 60s isn't the problem. setInterval will solve this but if within it I set an Interval of 5 min then every 10 seconds there will be a new 5 min interval set?
Thankyou very much for your help.
You are recursively setting intervals:
async function clock() {
//...
setInterval(() => clock(), 60000);
setInterval(() => {}, 60000*5);
}
So every time you call clock (every minute), you are setting more and more intervals for both clock and, well, an empty function. (It looks like you forgot to try to call serverTime?)
If you want to call clock every 60 seconds, then just set an interval to call it every 60 seconds:
async function clock() {
//...
}
setInterval(clock, 60000);
If you want to call serverTime every 5 minutes, then just set an interval to call it every 5 minutes:
async function serverTime() {
//...
}
setInterval(serverTime, 300000);
There's no need to do this recursively. Doing so means that setting an interval is part of the operation being repeated, which isn't what you want.
Edit: To demonstrate the problem, watch your browser console on this link: https://jsfiddle.net/Laqt4oe5 How many times do you expect the number to increase every 3 seconds? How many times is it actually increasing?
I have used this to solve the issue and obtain what i wanted
/**
* Display a digital clock
*
* #param {string} container - placement of the clock on the page
*/
function systemTime() {
let currentTime = new Date();
let diem = "AM";
let h = currentTime.getHours();
let m = currentTime.getMinutes();
let s = currentTime.getSeconds();
if (h == 0) h = 12;
if (h > 12) diem = "PM";
if (h < 10) h = "0" + h;
if (m < 10) m = "0" + m;
if (s < 10) s = "0" + s;
return {
h: h.toString(),
m: m.toString(),
diem: diem
}
}
/**
* Returns an object containing hours and minutes from the worldTimeAPI
*/
async function serverTime() {
let timeUrl = 'https://worldtimeapi.org/api/timezone/Europe/Berlin';
let response = await fetch(timeUrl);
let data = await response.json();
let timestamp = data.datetime;
let time = timestamp.split('T')[1].split('.')[0];
let timeArray = time.split(':');
if(parseInt(timeArray[0]) > 12) timeArray[2] = 'PM'
else timeArray[2] = 'AM';
console.log('Time fetched from world API');
return {
h: timeArray[0],
m: timeArray[1],
diem: timeArray[2]
}
}
/**
* Fires every 5 min and compares server and system times
*/
async function compareTime() {
let server = await serverTime();
let system = systemTime();
let container = document.querySelector('#displayClock');
if(system.h != server.h || system.m != server.m) container.innerHTML = `${server.h} : ${server.m} ${server.diem}`;
else container.innerHTML = `${system.h} : ${system.m} ${system.diem}`;
setInterval(() => compareTime(), 60000);
}
/**
* Fires every 1 min and displays system time
*/
function displayTime() {
let system = systemTime();
let h = system.h;
let m = system.m;
let diem = system.diem;
let container = document.querySelector('#displayClock');
container.innerHTML = `${h} : ${m} ${diem}`;
setInterval(() => displayTime(), 60000);
}
I'm new to JavaScript and I'm trying to write a code which calculates the time elapsed from the time a user logged in to the current time.
Here is my code:-
function markPresent() {
window.markDate = new Date();
$(document).ready(function() {
$("div.absent").toggleClass("present");
});
updateClock();
}
function updateClock() {
var markMinutes = markDate.getMinutes();
var markSeconds = markDate.getSeconds();
var currDate = new Date();
var currMinutes = currDate.getMinutes();
var currSeconds = currDate.getSeconds();
var minutes = currMinutes - markMinutes;
if(minutes < 0) { minutes += 60; }
var seconds = currSeconds - markSeconds;
if(seconds < 0) { seconds += 60; }
if(minutes < 10) { minutes = "0" + minutes; }
if(seconds < 10) { seconds = "0" + seconds; }
var hours = 0;
if(minutes == 59 && seconds == 59) { hours++; }
if(hours < 10) { hours = "0" + hours; }
var timeElapsed = hours+':'+minutes+':'+seconds;
document.getElementById("timer").innerHTML = timeElapsed;
setTimeout(function() {updateClock()}, 1000);
}
The output is correct upto 00:59:59 but after that that O/P is:
00:59:59
01:59:59
01:59:00
01:59:01
.
.
.
.
01:59:59
01:00:00
How can I solve this and is there a more efficient way I can do this?
Thank you.
No offence, but this is massively over-enginered. Simply store the start time when the script first runs, then subtract that from the current time every time your timer fires.
There are plenty of tutorials on converting ms into a readable timestamp, so that doesn't need to be covered here.
var start = Date.now();
setInterval(function() {
document.getElementById('difference').innerHTML = Date.now() - start;
// the difference will be in ms
}, 1000);
<div id="difference"></div>
There's too much going on here.
An easier way would just be to compare markDate to the current date each time and reformat.
See Demo: http://jsfiddle.net/7e4psrzu/
function markPresent() {
window.markDate = new Date();
$(document).ready(function() {
$("div.absent").toggleClass("present");
});
updateClock();
}
function updateClock() {
var currDate = new Date();
var diff = currDate - markDate;
document.getElementById("timer").innerHTML = format(diff/1000);
setTimeout(function() {updateClock()}, 1000);
}
function format(seconds)
{
var numhours = parseInt(Math.floor(((seconds % 31536000) % 86400) / 3600),10);
var numminutes = parseInt(Math.floor((((seconds % 31536000) % 86400) % 3600) / 60),10);
var numseconds = parseInt((((seconds % 31536000) % 86400) % 3600) % 60,10);
return ((numhours<10) ? "0" + numhours : numhours)
+ ":" + ((numminutes<10) ? "0" + numminutes : numminutes)
+ ":" + ((numseconds<10) ? "0" + numseconds : numseconds);
}
markPresent();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="timer"></div>
Here is a solution I just made for my use case. I find it is quite readable. The basic premise is to simply subtract the timestamp from the current timestamp, and then divide it by the correct units:
const showElapsedTime = (timestamp) => {
if (typeof timestamp !== 'number') return 'NaN'
const SECOND = 1000
const MINUTE = 1000 * 60
const HOUR = 1000 * 60 * 60
const DAY = 1000 * 60 * 60 * 24
const MONTH = 1000 * 60 * 60 * 24 * 30
const YEAR = 1000 * 60 * 60 * 24 * 30 * 12
// const elapsed = ((new Date()).valueOf() - timestamp)
const elapsed = 1541309742360 - timestamp
if (elapsed <= MINUTE) return `${Math.round(elapsed / SECOND)}s`
if (elapsed <= HOUR) return `${Math.round(elapsed / MINUTE)}m`
if (elapsed <= DAY) return `${Math.round(elapsed / HOUR)}h`
if (elapsed <= MONTH) return `${Math.round(elapsed / DAY)}d`
if (elapsed <= YEAR) return `${Math.round(elapsed / MONTH)}mo`
return `${Math.round(elapsed / YEAR)}y`
}
const createdAt = 1541301301000
console.log(showElapsedTime(createdAt + 5000000))
console.log(showElapsedTime(createdAt))
console.log(showElapsedTime(createdAt - 500000000))
For example, if 3000 milliseconds elapsed, then 3000 is greater than SECONDS (1000) but less than MINUTES (60,000), so this function will divide 3000 by 1000 and return 3s for 3 seconds elapsed.
If you need timestamps in seconds instead of milliseconds, change all instances of 1000 to 1 (which effectively multiplies everything by 1000 to go from milliseconds to seconds (ie: because 1000ms per 1s).
Here are the scaling units in more DRY form:
const SECOND = 1000
const MINUTE = SECOND * 60
const HOUR = MINUTE * 60
const DAY = HOUR * 24
const MONTH = DAY * 30
const YEAR = MONTH * 12
We can also use console.time() and console.timeEnd() method for the same thing.
Syntax:
console.time(label);
console.timeEnd(label);
Label:
The name to give the new timer. This will identify the timer; use the same name when calling console.timeEnd() to stop the timer and get the time output to the console.
let promise = new Promise((resolve, reject) => setTimeout(resolve, 400, 'resolved'));
// Start Timer
console.time('x');
promise.then((result) => {
console.log(result);
// End Timer
console.timeEnd('x');
});
You can simply use performance.now()
Example:
start = performance.now();
elapsedTime = performance.now() - start;
var hours = 0;
if(minutes == 59 && seconds == 59)
{
hours = hours + 1;
minutes = '00';
seconds == '00';
}
I would use the getTime() method, subtract the time and then convert the result into hh:mm:ss.mmm format.
I know this is kindda old question but I'd like to apport my own solution in case anyone would like to have a JS encapsulated plugin for this. Ideally I would have: start, pause, resume, stop, reset methods. Giving the following code all of the mentioned can easily be added.
(function(w){
var timeStart,
timeEnd,
started = false,
startTimer = function (){
this.timeStart = new Date();
this.started = true;
},
getPartial = function (end) {
if (!this.started)
return 0;
else {
if (end) this.started = false;
this.timeEnd = new Date();
return (this.timeEnd - this.timeStart) / 1000;
}
},
stopTime = function () {
if (!this.started)
return 0;
else {
return this.getPartial(true);
}
},
restartTimer = function(){
this.timeStart = new Date();
};
w.Timer = {
start : startTimer,
getPartial : getPartial,
stopTime : stopTime,
restart : restartTimer
};
})(this);
Start
Partial
Stop
Restart
What I found useful is a 'port' of a C++ construct (albeit often in C++ I left show implicitly called by destructor):
var trace = console.log
function elapsed(op) {
this.op = op
this.t0 = Date.now()
}
elapsed.prototype.show = function() {
trace.apply(null, [this.op, 'msec', Date.now() - this.t0, ':'].concat(Array.from(arguments)))
}
to be used - for instance:
function debug_counters() {
const e = new elapsed('debug_counters')
const to_show = visibleProducts().length
e.show('to_show', to_show)
}
I need to create a javascript timer that will count down to the next 5 minutes.
For example let's say the time is 00:07:30, the time will say 02:30
if the time is 15:42:00 the timer will say 03:00
I can't really think of any good way to du this.
thank you.
There are many ways to do this. My idea is to find out the reminder of current time divide by five minutes (300 seconds).
Demo : http://jsfiddle.net/txwsj/
setInterval(function () {
var d = new Date(); //get current time
var seconds = d.getMinutes() * 60 + d.getSeconds(); //convet current mm:ss to seconds for easier caculation, we don't care hours.
var fiveMin = 60 * 5; //five minutes is 300 seconds!
var timeleft = fiveMin - seconds % fiveMin; // let's say now is 01:30, then current seconds is 60+30 = 90. And 90%300 = 90, finally 300-90 = 210. That's the time left!
var result = parseInt(timeleft / 60) + ':' + timeleft % 60; //formart seconds back into mm:ss
document.getElementById('test').innerHTML = result;
}, 500) //calling it every 0.5 second to do a count down
Instead you could try using window.setInterval() like this:
window.setInterval(function(){
var time = document.getElementById("secs").innerHTML;
if (time > 0) {
time -= 1;
} else {
alert ("times up!");
//or whatever you want
}
document.getElementById("secs").innerHTML = time;
}, 1000);
const startMinutes = 1
let time = startMinutes * 60
const updateCountDown = () => {
const t = setInterval(() => {
const minutes = Math.floor(time / 60)
const seconds = time % 60
const result = `${parseInt(minutes)}:${parseInt(seconds)}`
document.getElementById('test').innerHTML = result
time--
if (minutes === 0 && seconds === 0) {
clearInterval(t)
}
}, 1000)
}
If you want to do a timer on your webpage, you can try to use something like this:
<html>
<head>
<script type="text/javascript">
var now = new Date().getTime();
var elapsed = new Date().getTime() - now;
document.getElementById("timer").innerHtml = elapsed;
if (elapsed > 300000 /*milliseconds in 5 minutes*/) {
alert ("5 minutes up!");
//take whatever action you want!
}
</script>
</head>
<body>
<div id="timer"></div>
</body>
</html>