I want to caluculate amout time slots avalible based on these inputs:
let start = req.body.start; //Start of hour
let end = req.body.end; // End of hour
let interval = req.body.interval // Interval that the timeslots are going to be set
So with the input of this:
start = 11:00
end = 19:00
interval = 30 //minutes
dif = end - start // as int not time
I want the output to be:
[11:00, 11:30, 12:00, 12:30, 13:00,
13:30, 14:00, 14:30, 15:00, 15:30,
16:00, 16:30, 17:00, 17:30, 18:00,
18:30, 19:00]
in string format of course
found a semi working suliton with the interval of 20 minutes:
for (let i = 0; i < dif; i++) {
let hourArray = [];
let hour = parseInt(start) + i;
for (let j = 0; j < 60 / interval; j++) {
let hourTime = `${hour}:${interval * j}`;
if (j === 0) {
hourTime = `${hour}:00`;
}
hourArray.push(hourTime);
}
console.log(hourArray);
}
We can start by converting hh:mm timeslots to minutes from midnight, we then get the start time and endtime in minutes - startMins and endMins
We'll then use a for loop to create each timeslot, adding interval minutes for each iteration.
Finally we'll output by converting each timeslot to hh:mm format.
function hhMMToMinutes(hhmm) {
const [hours, mins] = hhmm.split(':').map(Number);
return hours * 60 + mins;
}
function minutesToHHMM(minutes) {
const hours = Math.floor(minutes / 60);
const mins = minutes % 60;
return (hours + '').padStart(2, '0') + ':' + (mins + '').padStart(2, '0')
}
function getTimeSlots(start, end, interval) {
const startMins = hhMMToMinutes(start);
const endMins = hhMMToMinutes(end);
const result = [];
for (let mins = startMins; mins <= endMins; mins += interval) {
result.push(minutesToHHMM(mins))
}
return result;
}
console.log('Timeslots:', getTimeSlots('11:00', '19:00', 30))
.as-console-wrapper { max-height: 100% !important; }
Related
const createTimeSlots=(fromTime,toTime)=>{
I want to add 15 minutes slot to each StartTime in a loop and store in array of objects.
Assuming the inputs are in timestamp, add 15 mins equivalent of timestamps and push that timestamp(or push mins/hrs etc.). Here's the code example where start time is current timestamp and endtime is current + 3hrs in timestamp.
function createSlots(start, end) {
let slots = [];
const mins = 15 * 60 * 1000; // 15 mins
const date = (dt) => new Date(dt);
while (start <= end) {
start += mins;
// only mins
//slots.push(date(start).getMinutes());
// hrs + mins
slots.push(`${date(start).getHours()}:${date(start).getMinutes()}`);
}
return slots;
}
var slots = createSlots(Date.now(), Date.now() + 3 * 3600 * 1000); // from (now) to (now + 3hrs)
console.log("slots : ", slots);
Let's assume inputs are valid date-time format.
This solution will work across dates, let's say you give the start time today and end time tomorrow then also it will work without any issue.
const createTimeSlots = (fromTime, toTime, slotLength =15*60) => {
let slotStart = new Date(fromTime).valueOf();
let slotEnd = new Date(fromTime).valueOf() + slotLength * 1000;
let endEpoch = new Date(toTime).valueOf();
let ob = [];
for (slotEnd; slotEnd <= endEpoch; slotEnd = slotEnd + slotLength * 1000) {
ob.push({
'from': formatDate(slotStart),
'to': formatDate(slotEnd)
});
slotStart = slotEnd;
}
return ob;
}
function formatDate(epoch) {
let d = new Date(epoch);
let month = String((d.getMonth() + 1)).padStart(2, '0');
let day = String((d.getDate())).padStart(2, '0');
let hours = String((d.getHours())).padStart(2, '0');
let mins = String((d.getMinutes())).padStart(2, '0');
return `${d.getFullYear()}-${month}-${day} ${hours}:${mins}`;
}
const from = "2022-05-25 23:00";
const to = "2022-05-26 01:00";
const slotLength = 15 * 60; //seconds
var r = createTimeSlots(from, to, slotLength );
console.log(r);
I want to generate a list of time slots with an interval of 15 minutes. Now, like Googles calendar for example, I want it to start at 12:00am and after 12:00pm it should display 1:00am until 11:45am.
Here is what I got so far:
let x = 15;
let times = [];
let tt = 0;
let ap = ["AM", "PM"];
for (let i = 0; tt < 24 * 60; i++) {
let hh = Math.floor(tt / 60);
let mm = tt % 60;
times[i] = ("0" + (hh % 12)).slice(-2) + ":" + ("0" + mm).slice(-2) + ap[Math.floor(hh / 12)];
tt = tt + x;
}
console.log(times)
I created a jsfiddle to see it.
Like mentioned before I would like it to start at 12:00am and instead of 00:00pm it should display 12:00pm, then 12:15pm, then 12:30pm etc. etc.
How can I achieve that?
You can check if hh % 12 is equal 0:
let x = 15; //minutes interval
let times = []; // time array
let tt = 0; // start time
let ap = ["AM", "PM"]; // AM-PM
//loop to increment the time and push results in array
for (let i = 0; tt < 24 * 60; i++) {
let hh = Math.floor(tt / 60); // getting hours of day in 0-24 format
let mm = tt % 60; // getting minutes of the hour in 0-55 format
let hh12 = hh % 12;
if( hh12 === 0) {
hh12 = 12;
}
times[i] = ("0" + (hh12)).slice(-2) + ":" + ("0" + mm).slice(-2) + ap[Math.floor(hh / 12)]; // pushing data in array in [00:00 - 12:00 AM/PM format]
tt = tt + x;
}
console.log(times);
You could create a start date (at whichever time you wish), then keep adding your interval in minutes until you hit your desired end time (I'm assuming we'll generate slots for the whole day):
let date = new Date(2021, 1, 10, 12, 0, 0);
const intervalMinutes = 15;
const dom = date.getDate();
let times = [];
do {
times.push(date.toLocaleTimeString("en-US", { hour: '2-digit', minute: '2-digit' }))
date = new Date(date.setMinutes(date.getMinutes() + intervalMinutes));
} while (date.getDate() === dom)
console.log("Time slots:",times);
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 want timeslots from starting time and ending time with a given interval. also need to check that if the provided date is same as today's date then start time would be the current time of particular region. (like if time is 10:12 then we need to start from 10:30 and if time is 10:36 then opt for 11:00 (i.e. from 1 minute to 29 we should opt 30 minutes and from 31 to 59 we should opt 00) ).
So, how can I achieve that using given values below?
Input:
let date = "20-07-2019"
let startTime = "10:00";
let endtime = "14:00";
let interval = 60; // in minutes
Expected Output:
["10:00 - 11:00", "11:00- 12:00" , "12:00- 13:00", "13:00 - 14:00"]
My code:
let parseTime = (s) => {
let c = s.split(':');
return parseInt(c[0]) * 60 + parseInt(c[1]);
}
let convertHours = (mins) => {
let hour = Math.floor(mins / 60);
mins = mins % 60;
let converted = pad(hour, 2) + ':' + pad(mins, 2);
return converted;
}
let pad = (str, max) => {
str = str.toString();
return str.length < max ? pad("0" + str, max) : str;
}
let calculate_time_slot = (start_time, end_time, interval) => {
let i, formatted_time;
let time_slots = new Array();
for (let i = start_time; i <= end_time; i = i + interval) {
formatted_time = convertHours(i);
time_slots.push(formatted_time);
}
return time_slots;
}
let date = "20-07-2019"
let startTime = "10:00";
let endTime = "14:00";
let interval = 60; // in minutes
start_time = parseTime(startTime)
end_time = parseTime(endTime)
let times_ara = calculate_time_slot(start_time, end_time, interval);
console.log(times_ara);
I'd change the for loop to a while, then increment for the interval in the loop so you have both the start and end times in the loop, e.g.
let parseTime = (s) => {
let c = s.split(':');
return parseInt(c[0]) * 60 + parseInt(c[1]);
}
let convertHours = (mins) => {
let hour = Math.floor(mins / 60);
mins = mins % 60;
let converted = pad(hour, 2) + ':' + pad(mins, 2);
return converted;
}
let pad = (str, max) => {
str = str.toString();
return str.length < max ? pad("0" + str, max) : str;
}
let calculate_time_slot = (start_time, end_time, interval) => {
let i, formatted_time;
let time_slots = new Array();
// Round start and end times to next 30 min interval
start_time = Math.ceil(start_time / 30) * 30;
end_time = Math.ceil(end_time / 30) * 30;
// Start and end of interval in the loop
while (start_time < end_time) {
let t = convertHours(start_time) + ' - ' + (convertHours(start_time += interval));
time_slots.push(t);
}
return time_slots;
}
let date = "20-07-2019"
let startTime = "10:00";
let endtime = "14:00";
let interval = 60; // in minutes
let end_time = parseTime(endtime)
let start_time = parseTime(startTime)
let times_ara = calculate_time_slot(start_time, end_time, interval);
console.log(times_ara);
There's quite a bit of other stuff I'd change too, but that's the minimum to get your desired result.
Oh, I added a bit to round to the next 30 minute interval 'cos that's what you said you wanted too.
Your function seems to generate the required values you just need to change how they are represented, here is a way of doing that:
let time_slots = ["10:00", "11:00", "12:00", "13:00", "14:00"];
time_slots = time_slots.reduce((a, c, i, arr) => {
if (i < arr.length - 1) {
a.push(`${c} - ${arr[i + 1]}`);
}
return a;
}, []);
console.log(time_slots);
This is the shortest I got.
let calculate_time_slot = (start_time, end_time, interval) => {
const timeSlots = [];
for (let i = start_time; i < end_time; i += interval) {
const formattedBegin = convertHours(i);
const formattedEnd = convertHours(i + interval);
timeSlots.push(formattedBegin + ' - ' + formattedEnd);
}
return timeSlots;
}
Runnable snippet:
let parseTime = (s) => {
let c = s.split(':');
return parseInt(c[0]) * 60 + parseInt(c[1]);
}
let convertHours = (mins) => {
let hour = Math.floor(mins / 60);
mins = mins % 60;
let converted = pad(hour, 2) + ':' + pad(mins, 2);
return converted;
}
let pad = (str, max) => {
str = str.toString();
return str.length < max ? pad("0" + str, max) : str;
}
let calculate_time_slot = (start_time, end_time, interval) => {
const timeSlots = [];
for (let i = start_time; i < end_time; i += interval) {
const formattedBegin = convertHours(i);
const formattedEnd = convertHours(i + interval);
timeSlots.push(formattedBegin + ' - ' + formattedEnd);
}
return timeSlots;
}
let date = "20-07-2019"
let startTime = "10:00";
let endTime = "14:00";
let interval = 60; // in minutes
start_time = parseTime(startTime)
end_time = parseTime(endTime)
let times_ara = calculate_time_slot(start_time, end_time, interval);
console.log(times_ara);
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)
}