How to subtract date and time in javascript? - javascript

I have a Check-In app that when the button to Check In is clicked, it fetches an API and returns me the current date and time (2023-01-12T12:59:49.090Z). You can then click it again later but for Check Out. What I'm trying to do now is subtract one from the other as to calculate the total hours worked per employee.
I've tried a bunch of different methods but here's what its looking like:
function renderTable(data) {
const tbCheckins = document.getElementById('tbCheckins')
tbCheckins.innerHTML = ""
data.forEach(function(item) {
console.log('Item:', item)
const rowElement = document.createElement(`tr`)
createRowCell(rowElement, new Date(item.checkin_time).toLocaleTimeString())
const checkoutValue = item.checkout_time == null ? "----" : new Date(item.checkout_time).toLocaleTimeString()
createRowCell(rowElement,checkoutValue)
createRowCell(rowElement, calcTotalHours())
createRowButtons(rowElement, item.id)
tbCheckins.appendChild(rowElement)
});
}
function calcTotalHours(){
var checkOutTime = new Date(item.checkout_time)
var checkInTime = new Date(item.checkin_time)}
var diffHours = Math.abs (checkOutTime - checkInTime)
days = diffHours/(1000 * 3600 * 24)
It is saying that checkOutTime and checkInTime are declared but are not being read.

You need to pass the variable item to the function calcTotalHours()
createRowCell(rowElement, calcTotalHours(item))
and redefine the function as
function calcTotalHours(item){
var checkOutTime = new Date(item.checkout_time)
var checkInTime = new Date(item.checkin_time)}
var diffHours = Math.abs (checkOutTime - checkInTime)
days = diffHours/(1000 * 3600 * 24)
return diffHours // this line was not in your example but I assume it should be
}
Otherwise the variable item will be undefined inside calcTotalHours()

Related

Increase a number based on Date or Interval javascript (and keep it after refresh page)

I'm struggling for while trying to figure out how to increase a number based on a Date or based on a time (Using setInterval).
I don't know which option is easier. I made it by using setInterval:
HTML
<p class="counter"></p>
JS
let tickets = 35000;
const counter = document.querySelector('.counter');
let interval = setInterval(function(){
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
}else{
var text = `¡${tickets} tickets Sold!`;
contador.innerHTML = text;
console.log(text)
}
const random = Math.floor(Math.random()*(200-100+1)+100);
tickets += random;
}, 10000);
The thing is every time the page is refreshed the counter starts from 35000 again. I am trying to figure out how to storage the var tickets. I guess this would be made by using localStorage, but since I am a beginner in JS, I am not able to do it.
Other option would be by checking the date, and based on that, show a number:
function date() {
var d = new Date();
var month = d.getMonth();
var day = d.getDate();
const counter = document.querySelector('.contador');
const random = Math.floor(Math.random()*(200-100+1)+100);
for (let i = 350000; i <= 60000 ; i++) {
if (month == 0 & day == 28) {
var sum = i + random;
document.getElementById("contador").innerHTML = suma;
}else if (mes == 0 & dia == 30) {
...
} else if (...){
...
}
}
document.getElementById("dia").innerHTML = dia;
document.getElementById("mes").innerHTML = mes;
}
fecha();
Could someone help me out to reach the result?
I would really appreciate it
The Storage object accessible via the localStorage property offers two methods to save or retrieve data: setItem and getItem().
Usage is quite simple. If you want to save the numbers of tickets into a myTickets key on localStorage you have to do it like this:
localStorage.setItem("myTickets", tickets);
To retrieve that data later on:
localStorage.getItem("myTickets");
You just have to make sure to update the myTickets key on localStorage as you increase the number of tickets inside the setinterval callback function.
let tickets = 35000;
if (localStorage.getItem("myTickets") == null) {
localStorage.setItem("myTickets", tickets);
} else {
tickets = localStorage.getItem("myTickets");
}
const counter = document.querySelector('.counter');
let interval = setInterval(function() {
console.log(tickets);
if (tickets >= 60000) {
var textSoldOut = `<p>¡Todo vendido!</p>`;
counter.innerHTML = textSoldOut;
console.log("Sold out");
clearInterval(interval);
} else {
var text = `¡${tickets} tickets Sold!`;
console.log(text)
}
const random = Math.floor(Math.random() * (200 - 100 + 1) + 100);
tickets += random;
localStorage.setItem("myTickets", tickets);
}, 10000);

How to stop Javascript counter after initial result is returned

I need to stop a counter after returning its initial result so that the result can then be innerHTL inserted as a static number off which subsequent, separate scripts rely.
The counter works great for continual counting, but I can't stop the darned thing for the life of me.
I've tried clearInterval, stopPropagation, modifying variables, but I'm honestly just too much of a disaster to know where to make those (or other) changes to stop and hold the initial returned value.
var counterData = {'startCounter':'1','startingDate':'02\/01\/2019','incrementPerSecond':'2','counterInterval':'3'};
var canYouBelieveThisGuy = function () {
'use strict';
if ($("#stat_counter").length > 0) {
var currentstat = parseFloat(counterData['startCounter'].replace(/[^\d.-]/g,''));
var intervalSeconds = counterData['counterInterval'] * 1000; //1000;
var increaseUnit = counterData['incrementPerSecond'];
var initialDate = new Date(counterData["startingDate"]);
setInterval(function () {
var currentDate = new Date();
var timeDiffSeconds = (currentDate - initialDate)/1000;
var increment = timeDiffSeconds * increaseUnit;
var currentstat2 = parseInt(currentstat + increment) * 100;
currentstat2 = (currentstat2 / 100).toFixed(0)
var num = (currentstat2);
$("#stat_counter").text(num);
}, intervalSeconds);
};
}
(jQuery, this);
The returned value should be the number produced after the initial run, and should stop running entirely thereafter.
Thanks for the help and for being gentle!

Find values in array depending on a pattern in Javascript

I have an array:
var videoSources = ["0000.mp4", "0015.mp4", "0030.mp4", "0045.mp4", "0100.mp4"];
I would play videos based on current time; mp4 are recorded every 15minutes;
if time = 0044 play 0030.mp4
So I need something like a pattern [0-15] to find and play correct video.
Here function to play video at the moment:
var currentIndex = 0;
// listener function changes src
function myNewSrc() {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = videoSources[currentIndex];
myVideo.load();
}
I'd suggest parseing the file name to an integer and then finding if a minute mark is within the range of the file:
var videoSources =
["0000.mp4",
"0015.mp4",
"0030.mp4",
"0045.mp4",
"0100.mp4"]
var getTimestamp = (ts, sources) =>
sources.find(name => {
const startStr = name.split(".")[0]; // e.g.: "0015"
const startMin = parseInt(startStr, 10); // e.g.: 15
const endMin = startMin + 15;
return ts >= startMin && ts < endMin;
});
console.log(getTimestamp(44, videoSources));
If the ranges aren't guaranteed to be 15 minutes, you could do a "look ahead" to find the end of a range. In my current example, I've hardcoded it to be 15 minutes, and expect the file name to be the start of the file.
Edit: to support hours and minutes
var videoSources =
["0000.mp4",
"0015.mp4",
"0030.mp4",
"0045.mp4",
"0100.mp4",
"1145.mp4",
"1230.mp4",
"1245.mp4"]
var getTimestamp = (h, m, sources) =>
sources
.sort()
.find(name => {
const hours = parseInt(name.slice(0, 2), 10);
const minutesStart = parseInt(name.slice(2, 4), 10);
const minutesEnd = minutesStart + 15;
return h <= hours && m >= minutesStart && m < minutesEnd;
});
console.log(getTimestamp(12, 44, videoSources));
You could map your times array and time to numbers and then use findIndex method to return index of correct time element from array.
var videoSources = ["0000.mp4", "0015.mp4", "0030.mp4", "0045.mp4", "0100.mp4"]
const getIndex = (arr, time) => {
time = parseInt(time);
arr = arr.map(e => parseInt(e.split('.')[0]));
return arr.findIndex((e, i) => time >= e && !arr[i + 1] || time < arr[i + 1]);
}
console.log(getIndex(videoSources, "0044"))
console.log(getIndex(videoSources, "0015"))
console.log(getIndex(videoSources, "0099"))
console.log(getIndex(videoSources, "0120"))

reloading div doesn't update time if it's called from another function

I have a time function
function hm()
{
var d = new Date();
var h = ('0'+d.getHours()).substr(-2);
var m = ('0'+d.getMinutes()).substr(-2);
var str0 = h + ':' + m;
return {date: str0, hour: h, minute: m};
}
var hm = hm();
var date = hm.date;
var hour = hm.hour;
var minute = hm.minute;
and I have a div
<div id="mytime">Time</div>
I call time function from this which updates the div
function refreshDiv() {
document.getElementById('mytimer').innerHTML = 'Time:.....' + hm.date;
}
$(document).ready(function () {
setInterval(refreshDiv, 5000);
});
It won't update the time like 12:03 12:04 but if I place function hm() and variables var hm = hm(); var date = hm.date; into function refreshDiv() block it works.
How can I make it work?
EDIT:
This is a nwjs project.
If I add hm = hm(); inside refreshDiv() I get:
"Uncaught TypeError: object is not a function", source: file:///home/.../index.html (182)
182 is line number of included hm = hm();
You don't need to store individual values:
var hm = hm();
var date = hm.date;
var hour = hm.hour;
var minute = hm.minute;
You have a function hm(): call it, and immediately get the value of a returned object:
document.getElementById('mytimer').innerHTML = 'Time: ' + hm().date;
Why? Let's use Chrome DevTools to clarify this.
So, you defined a function hm().
When you call it, you get the returned object: {a: 0000000000000, b: "test"}
You can access the fields of this object with .
var object = hm(); // Assign the returned value of hm() to object
alert(object.a); // Alerts value of the field a of object
If you don't want to allocate new variables, use hm().a. You will conserve memory and time.

Calculate unique time given multiple start and end dates

If you have an array of appointments with start and end dates how do you calculate the unique time for all of the appointments?
Example:
var appointments = {
0:{"start":"2015-01-20 09:00:00","end":"2015-01-20 09:30:00"},
1:{"start":"2015-01-20 09:15:00","end":"2015-01-20 09:42:22"},
2:{"start":"2015-01-20 10:00:00","end":"2015-01-20 10:25:00"},
3:{"start":"2015-01-20 10:10:00","end":"2015-01-20 10:53:00"}
}
So in this example I would want to get a unique time (activity) value of 1H 35M 22S.
Anyone know any formulas for this?
So far I have this, seems to work but I think dates have to be sorted by start time. Is this the most efficient way to calculate this?:
var totalElapsedAppointmentSeconds = 0;
var lastActiveTimestamp;
for (i in appointments) {
if (totalElapsedAppointmentSeconds == 0) {
totalElapsedAppointmentSeconds = new Date(appointments[i].end) - new Date(appointments[i].start);
lastActiveTimestamp = new Date(appointments[i].end);
} else {
if (new Date(appointments[i].start) < lastActiveTimestamp) {
if (new Date(appointments[i].end) > lastActiveTimestamp) {
totalElapsedAppointmentSeconds += new Date(appointments[i].end) - lastActiveTimestamp;
lastActiveTimestamp = new Date(appointments[i].end);
} else {
//nothing, already completely accounted for
}
} else {
totalElapsedAppointmentSeconds += new Date(appointments[i].end) - new Date(appointments[i].start);
lastActiveTimestamp = new Date(appointments[i].end);
}
}
}
totalElapsedAppointmentSeconds = totalElapsedAppointmentSeconds/1000;
var totalElapsedTime = Math.floor(totalElapsedAppointmentSeconds / 3600) + "H " + Math.floor((totalElapsedAppointmentSeconds % 3600)/60) + "M " + (totalElapsedAppointmentSeconds % 3600) % 60 + "S";
console.log("totalElapsedTime",totalElapsedTime);
unclear what you are asking but this demonstrates calculating a time difference
EDIT whoops javascript says these are invalid dates, where did they come from?
moment.js is a good option to parse them if you must use these as inputs
var data = {
"appointments": {
0:{"start":"2015-01-20 09:00:00","end":"2015-01-20 09:30:00"},
1:{"start":"20-01-2015 09:15:00","end":"20-01-2015 09:42:22"},
2:{"start":"20-01-2015 10:00:00","end":"20-01-2015 10:25:00"},
3:{"start":"20-01-2015 10:10:00","end":"20-01-2015 10:53:00"},
}
}
function secondsDifference(ts1, ts2){
startMs = new Date(ts1).valueOf();
endMs = new Date(ts2).valueOf();
deltaMs = endMs - startMs;
deltaS = deltaMs /1000;
deltaS = Math.floor(deltaS);
return deltaS;
}
var a = data.appointments[0];
var result = secondsDifference(a.start, a.end);
console.log('first appointment length seconds:', result)

Categories