Calculate difference between dates and start counting from that difference - javascript

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

Related

Put clock forward by one hour [duplicate]

It amazes me that JavaScript's Date object does not implement an add function of any kind.
I simply want a function that can do this:
var now = Date.now();
var fourHoursLater = now.addHours(4);
function Date.prototype.addHours(h) {
// How do I implement this?
}
I would simply like some pointers in a direction.
Do I need to do string parsing?
Can I use setTime?
How about milliseconds?
Like this:
new Date(milliseconds + 4*3600*1000 /* 4 hours in ms */)?
This seems really hackish though - and does it even work?
JavaScript itself has terrible Date/Time API's. Nonetheless, you can do this in pure JavaScript:
Date.prototype.addHours = function(h) {
this.setTime(this.getTime() + (h*60*60*1000));
return this;
}
Date.prototype.addHours= function(h){
this.setHours(this.getHours()+h);
return this;
}
Test:
alert(new Date().addHours(4));
The below code will add 4 hours to a date (example, today's date):
var today = new Date();
today.setHours(today.getHours() + 4);
It will not cause an error if you try to add 4 to 23 (see the documentation):
If a parameter you specify is outside of the expected range, setHours() attempts to update the date information in the Date object accordingly
It is probably better to make the addHours method immutable by returning a copy of the Date object rather than mutating its parameter.
Date.prototype.addHours= function(h){
var copiedDate = new Date(this.getTime());
copiedDate.setHours(copiedDate.getHours()+h);
return copiedDate;
}
This way you can chain a bunch of method calls without worrying about state.
The version suggested by kennebec will fail when changing to or from DST, since it is the hour number that is set.
this.setUTCHours(this.getUTCHours()+h);
will add h hours to this independent of time system peculiarities.
Jason Harwig's method works as well.
Get a date exactly two hours from now, in one line.
You need to pass milliseconds to new Date.
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
or
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
let nowDate = new Date();
let expiryDate = new Date(new Date().setHours(new Date().getHours() + 2));
let expiryDate2 = new Date(Date.now() + 2 * (60 * 60 * 1000) );
console.log('now', nowDate);
console.log('expiry', expiryDate);
console.log('expiry 2', expiryDate2);
You can use the Moment.js library.
var moment = require('moment');
foo = new moment(something).add(10, 'm').toDate();
I also think the original object should not be modified. So to save future manpower here's a combined solution based on Jason Harwig's and Tahir Hasan answers:
Date.prototype.addHours= function(h){
var copiedDate = new Date();
copiedDate.setTime(this.getTime() + (h*60*60*1000));
return copiedDate;
}
If you would like to do it in a more functional way (immutability) I would return a new date object instead of modifying the existing and I wouldn't alter the prototype but create a standalone function. Here is the example:
//JS
function addHoursToDate(date, hours) {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
//TS
function addHoursToDate(date: Date, hours: number): Date {
return new Date(new Date(date).setHours(date.getHours() + hours));
}
let myDate = new Date();
console.log(myDate)
console.log(addHoursToDate(myDate,2))
There is an add in the Datejs library.
And here are the JavaScript date methods. kennebec wisely mentioned getHours() and setHours();
Check if it’s not already defined. Otherwise, define it in the Date prototype:
if (!Date.prototype.addHours) {
Date.prototype.addHours = function(h) {
this.setHours(this.getHours() + h);
return this;
};
}
This is an easy way to get an incremented or decremented data value.
const date = new Date()
const inc = 1000 * 60 * 60 // an hour
const dec = (1000 * 60 * 60) * -1 // an hour
const _date = new Date(date)
return new Date(_date.getTime() + inc)
return new Date(_date.getTime() + dec)
Another way to handle this is to convert the date to unixtime (epoch), then add the equivalent in (milli)seconds, then convert it back. This way you can handle day and month transitions, like adding 4 hours to 21, which should result in the next day, 01:00.
SPRBRN is correct. In order to account for the beginning/end of the month and year, you need to convert to Epoch and back.
Here's how you do that:
var milliseconds = 0; //amount of time from current date/time
var sec = 0; //(+): future
var min = 0; //(-): past
var hours = 2;
var days = 0;
var startDate = new Date(); //start date in local time (we'll use current time as an example)
var time = startDate.getTime(); //convert to milliseconds since epoch
//add time difference
var newTime = time + milliseconds + (1000*sec) + (1000*60*min) + (1000*60*60*hrs) + (1000*60*60*24*days);
var newDate = new Date(newTime); //convert back to date; in this example: 2 hours from right now
Or do it in one line (where variable names are the same as above:
var newDate =
new Date(startDate.getTime() + millisecond +
1000 * (sec + 60 * (min + 60 * (hours + 24 * days))));
For a simple add/subtract hour/minute function in JavaScript, try this:
function getTime (addHour, addMin){
addHour = (addHour ? addHour : 0);
addMin = (addMin ? addMin : 0);
var time = new Date(new Date().getTime());
var AM = true;
var ndble = 0;
var hours, newHour, overHour, newMin, overMin;
// Change form 24 to 12 hour clock
if(time.getHours() >= 13){
hours = time.getHours() - 12;
AM = (hours>=12 ? true : false);
}else{
hours = time.getHours();
AM = (hours>=12 ? false : true);
}
// Get the current minutes
var minutes = time.getMinutes();
// Set minute
if((minutes + addMin) >= 60 || (minutes + addMin) < 0){
overMin = (minutes + addMin) % 60;
overHour = Math.floor((minutes + addMin - Math.abs(overMin))/60);
if(overMin < 0){
overMin = overMin + 60;
overHour = overHour-Math.floor(overMin/60);
}
newMin = String((overMin<10 ? '0' : '') + overMin);
addHour = addHour + overHour;
}else{
newMin = minutes + addMin;
newMin = String((newMin<10 ? '0' : '') + newMin);
}
// Set hour
if((hours + addHour >= 13) || (hours + addHour <= 0)){
overHour = (hours + addHour) % 12;
ndble = Math.floor(Math.abs((hours + addHour)/12));
if(overHour <= 0){
newHour = overHour + 12;
if(overHour == 0){
ndble++;
}
}else{
if(overHour == 0){
newHour = 12;
ndble++;
}else{
ndble++;
newHour = overHour;
}
}
newHour = (newHour<10 ? '0' : '') + String(newHour);
AM = ((ndble + 1) % 2 === 0) ? AM : !AM;
}else{
AM = (hours + addHour == 12 ? !AM : AM);
newHour = String((Number(hours) + addHour < 10 ? '0': '') + (hours + addHour));
}
var am = (AM) ? 'AM' : 'PM';
return new Array(newHour, newMin, am);
};
This can be used without parameters to get the current time:
getTime();
Or with parameters to get the time with the added minutes/hours:
getTime(1, 30); // Adds 1.5 hours to current time
getTime(2); // Adds 2 hours to current time
getTime(0, 120); // Same as above
Even negative time works:
getTime(-1, -30); // Subtracts 1.5 hours from current time
This function returns an array of:
array([Hour], [Minute], [Meridian])
If you need it as a string, for example:
var defaultTime: new Date().getHours() + 1 + ":" + new Date().getMinutes();
I think this should do the trick
var nextHour = Date.now() + 1000 * 60 * 60;
console.log(nextHour)
You can even format the date in desired format using the moment function after adding 2 hours.
var time = moment(new Date(new Date().setHours(new Date().getHours() + 2))).format("YYYY-MM-DD");
console.log(time);
A little messy, but it works!
Given a date format like this: 2019-04-03T15:58
//Get the start date.
var start = $("#start_date").val();
//Split the date and time.
var startarray = start.split("T");
var date = startarray[0];
var time = startarray[1];
//Split the hours and minutes.
var timearray = time.split(":");
var hour = timearray[0];
var minute = timearray[1];
//Add an hour to the hour.
hour++;
//$("#end_date").val = start;
$("#end_date").val(""+date+"T"+hour+":"+minute+"");
Your output would be: 2019-04-03T16:58
The easiest way to do it is:
var d = new Date();
d = new Date(d.setHours(d.getHours() + 2));
It will add 2 hours to the current time.
The value of d = Sat Jan 30 2021 23:41:43 GMT+0500 (Pakistan Standard Time).
The value of d after adding 2 hours = Sun Jan 31 2021 01:41:43 GMT+0500 (Pakistan Standard Time).

How can I round time to hours and minutes instead of hours, minutes and seconds?

My function returns the time like this 10:43:22 for example. How can I round the time to the closest minute so 10:43:22 becomes 10:43 and 10:43:44 becomes 10:44.
function time (){
let date = new Date()
let time = date.toLocaleTimeString("it-IT");
}
I would get the milliseconds of that date and then round that value to minutes (1 minute = 60,000 milliseconds).
function createRoundedDate(date) {
var ts = date.getTime();
ts = Math.round(ts / 60000) * 60000;
return new Date(ts);
}
console.log(createRoundedDate(new Date()))
we can use the below code to create the new Date by removing the seconds part
var d = new Date()
var d1 = new Date(d.getYear(),d.getMonth(),d.getDate(),d.getHours(),d.getMinutes())
console.log(d1.toLocaleTimeString('it-IT'))
This should do it, and handle going over hours etc. (60,000 ticks is 1 min)
function time(){
let date = new Date()
let dateMins = new Date(date.getYear(),date.getMonth(),date.getDay(),date.getHours(),date.getMinutes())
let roundedDate = new Date(dateMins.getTime() + date.getSeconds() > 30 ? 60000 : 0 )
let time = roundedDate.toLocaleTimeString("it-IT");
}

Difference between dates erroneously calculating getHours?

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));
})()

Jquery timer with UTC offset

function getMinutesUntilNextHour() {
var now = new Date();
var hours = now.getUTCHours();
var mins = now.getMinutes();
var secs = now.getSeconds();
// Compute time remaining per unit
var cur_hours = 23 - hours;
var cur_mins = 60 - mins;
var cur_secs = 60 - secs;
// Correct zero padding of hours if needed
if (cur_hours < 10) {
cur_hours = '0' + cur_hours;
}
// Correct zero padding of minutes if needed
if (cur_mins < 10) {
cur_mins = '0' + cur_mins;
Here’s the code for a simple 24 hour countdown timer that resets again after each 24 hours but when I add, say, 11- hours in the compute time remaining section it occasionally throws a negative time (in hours) at me depending on the current UTC time. I’d just like the 24 hour period to start from a different time /time zone. All help greatly appreciated
You might be looking at this backwards :-) Why don't you create a Date object for midnight, then subtract current time from it. This example works for the local timezone, but you could easily adapt it for UTC, or another timezone.
// We're going to use Vue to update the page each time our counter changes.
// You could also do this old style, updating the DOM directly.
// vueStore is just a global variable that will contain the current time,
// and the function to periodically update it.
var vueStore = {
now: new Date(),
countdown(){
vueStore.now = new Date();
window.setTimeout(() => {this.countdown(); }, 1000);
}
};
vueStore.countdown();
var vm = new Vue({
el: "#vueRoot",
data: { vueStore: vueStore },
computed: {
timeTilMidnight() {
var midnightTonight = new Date(this.vueStore.now.getYear(), this.vueStore.now.getMonth(), this.vueStore.now.getDay() + 1);
var timeToMidnight = midnightTonight.getTime() - this.vueStore.now.getTime();
return new Date(timeToMidnight).toLocaleTimeString([], {
timeZone: "UTC"
});
}
}
});
<script src="https://unpkg.com/vue#2.5.17/dist/vue.js"></script>
<div id="vueRoot">
<h1>{{timeTilMidnight}}</h1>
</div>

Find elapsed time in javascript

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)
}

Categories