I have two textbox with value to set start time and end time. If user has selected these times then it will be display those value. But, if user is creating a new appointment then by default it should display nearest half an hour time to current one and end time should be next hour duration.
For example,
The current time is 4:37PM then the start time should be 5:00PM and end time should be 6:00PM
If the current time is 7:31AM then the start time should be 8:00AM and end time should be 9:00AM.
If the current time is 11:45AM then the start time should be 12:00PM and end time should 01:00PM
This involves some fairly simple calculations, and Math.ceil:
const secsPerHalfHour = 1000 * 60 * 30
const nextHalfHour = () =>
new Date (Math .ceil (new Date() .getTime() / secsPerHalfHour) * secsPerHalfHour)
const next90Mins = () =>
new Date (Math .ceil ((new Date() .getTime() / secsPerHalfHour) + 2) * secsPerHalfHour)
console .log (`start: ${nextHalfHour()}`)
console .log (`end: ${next90Mins()}`)
I updated the example a bit, so that when the user sets in 8:00 it stays at 8:00, anything else goes to the next 30 minutes (which you could easily change)
A downside of this approach is that setting 8:30 makes it 9:00 as well, whereas you could possibly argue that 8:30 is valid as well, as it is at 30 minutes intervals
window.addEventListener('load', function() {
const startElement = document.querySelector('#startTime');
const endElement = document.querySelector('#endTime');
const detailsElement = document.querySelector('#appointment_details');
function createTimeString( hours, minutes ) {
if (hours < 0 || minutes < 0) {
throw 'argument exception';
}
console.log( 'original input ' + hours + ':' + minutes );
while (parseInt(hours) >= 24) hours = +hours - 24;
while (parseInt(minutes) >= 60) {
minutes = +minutes - 60;
hours = +hours + 1;
}
return hours.toString().padStart(2, '0') + ':' + minutes.toString().padStart(2, '0');
}
function handleStartTimeChanged( e ) {
const timeValue = e.target.value;
let [hours,minutes] = timeValue.split(':');
if (Math.round( parseInt( minutes ) / 60.0) === 1) {
hours = parseInt(hours) + 1;
minutes = 0;
} else if (parseInt( minutes ) !== 0) {
// anything else is same hour but 30 minutes past
minutes = 30;
}
setAppointmentDetails( createTimeString( hours, minutes ), createTimeString( +hours + 1, minutes ) );
}
function handleEndTimeChanged( e ) {
const timeValue = e.target.value;
let [hours,minutes] = timeValue.split(':');
if (Math.round( parseInt( minutes ) / 60.0) === 1) {
hours = parseInt(hours) + 1;
minutes = 0;
} else if (parseInt( minutes ) !== 0) {
// anything else is same hour but 30 minutes past
minutes = 30;
}
setAppointmentDetails( createTimeString( hours - 1, minutes ), createTimeString( hours, minutes ) );
}
function setAppointmentDetails( startTime, endTime ) {
detailsElement.innerHTML = `${startTime} till ${endTime}`;
}
startElement.addEventListener('change', handleStartTimeChanged );
endElement.addEventListener('change', handleEndTimeChanged );
} );
<div class="line">
<span class="label">Appointment start:</span>
<span class="field"><input type="time" id="startTime" /></span>
<span class="label">Appointment end:</span>
<span class="field"><input type="time" id="endTime" /></span>
</div>
<div id="appointment_details">
</div>
Related
so for a while I ve been trying to implement a script that prints me the remaining time (countdown) to an specific day of the week (Sunday) at 16 h (4PM), my server date timezone is set to America/New_York (GMT-5).. so far I have this code, it is not working well, only when countdown remaining time is less/under than 1 day, script start showing negative values (like, -1 hour..) any help here? cheers
https://jsfiddle.net/v4wjbtus/
function plural(s, i) {
return i + ' ' + (i > 1 ? s + 's' : s);
}
function sundayDelta(offset) {
// offset is in hours, so convert to miliseconds
offset = offset ? offset * 60 * 60 * 1000 : 0;
var now = new Date(new Date().getTime() + offset);
var days = 7 - now.getDay() || 7;
var hours = 21 - now.getHours() || 24;
var minutes = 60 - now.getMinutes();
var seconds = 60 - now.getSeconds();
return [plural('day', days),
plural('hour', hours),
plural('minute', minutes),
plural('second', seconds)].join(' ');
}
// Save reference to the DIV
$refresh = jQuery('#refresh');
$refresh.text('News in ' + sundayDelta());
// Update DIV contents every second
setInterval(function() {
$refresh.text('News in ' + sundayDelta());
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="refresh" class="text-success" style="position: absolute;bottom: 0;"></div>
Since there are already examples of converting milliseconds duration to human-readable form, I instead created a mashup with your code and what I found.
For my tastes, I would further update this to not show a segment if the segment equals zero, so that it reads better.
// seed date, (ANY past sunday at 16:00)
var seed = new Date(2020, 11, 6, 16);
var target;
// pluralize/singularize
function plural(s, i) {
return i + ' ' + (i > 1 ? s + 's' : s);
}
// miliseconds to the next upcoming sunday 16:00
function timeToTarget() {
while (seed < new Date()) {
seed.setDate(seed.getDate()+7)
}
target = seed;
return Math.abs(seed - new Date());
}
// convert miliseconds duration to human readable
function msReadableDuration() {
var duration = timeToTarget();
var seconds = Math.floor((duration / 1000) % 60),
minutes = Math.floor((duration / (1000 * 60)) % 60),
hours = Math.floor((duration / (1000 * 60 * 60)) % 24),
days = Math.floor((duration / (24 * 60 * 60 * 1000) % 7));
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
return [plural('day', days),
plural('hour', hours),
plural('minute', minutes),
plural('second', seconds)].join(', ');
}
// show seed date
$seed = jQuery('#seed');
$seed.text(seed.toString());
// Save reference to the DIV
$refresh = jQuery('#refresh');
$refresh.text('News in ' + msReadableDuration());
// Update DIV contents every second
setInterval(function() {
$refresh.text('News in ' + msReadableDuration());
}, 1000);
// show seed date (target is computed after timeToTarget executes)
$target = jQuery('#target');
$target.text(target.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="seed"></div>
<div id="target"></div>
<p id="refresh"></p>
And instead of using a seed date, you can further refine my snippet to have a function that simply looks for the next up-coming Sunday via something similar to this: https://codereview.stackexchange.com/a/33648
I'm creating a system where I have to check the deadline based on the client's initialization. For example, if the client's initialization was today at time x and the deadline is tomorrow or future at time y, I would like to calculate the time remaining inform of a countdown timer. I have managed to get the time remaining and my problem is count down timer to show the remaining days, hours, minutes, and seconds.
The following HTML code indicates the remaining time to the deadline
<span style='color: green;'>
<span class='e-m-days'>0</span> Days |
<span class='e-m-hours'>8</span> Hours |
<span class='e-m-minutes'>0</span> Minutes |
<span class='e-m-seconds'>1</span> Seconds
</span>
My jQuery code:
<script>
$(function(){
var days = parseInt( $('.e-m-days').html() );
var hours = parseInt( $('.e-m-hours').html() );
var minutes = parseInt( $('.e-m-minutes').html() );
var seconds = parseInt( $('.e-m-seconds').html() );
var minutesWrap = 0;
var hoursWrap = 0;
var daysWrap;
var hoursRem = hours;
var timer = seconds;
var counter =seconds;
function countOrdersRemainingTime(){
var id = setTimeout(countOrdersRemainingTime, 1000);
if(timer < 0){
minutesWrap ++;
timer = 59;
}
var minRem = minutes - minutesWrap;
if( minRem == -1 ){
hoursWrap + 1;
minRem = 59;
var hoursRem = hours - 1;
}
if(days == 0 && hours == 0 && minutes == 0 && seconds == 0){
clearTimeout(id);
}
$('.e-m-seconds').html(timer);
$('.e-m-minutes').html(minRem);
$('.e-m-hours').html(hoursRem);
timer --;
}
countOrdersRemainingTime();
});
</script>
The key thing is to create a count down timer that counts until the deadline is reached, i.e until the number of days, hours, minutes, and seconds becomes zero. I have tried for hours with no success :(.
Consider the following example.
$(function() {
function getCounterData(obj) {
var days = parseInt($('.e-m-days', obj).text());
var hours = parseInt($('.e-m-hours', obj).text());
var minutes = parseInt($('.e-m-minutes', obj).text());
var seconds = parseInt($('.e-m-seconds', obj).text());
return seconds + (minutes * 60) + (hours * 3600) + (days * 3600 * 24);
}
function setCounterData(s, obj) {
var days = Math.floor(s / (3600 * 24));
var hours = Math.floor((s % (60 * 60 * 24)) / (3600));
var minutes = Math.floor((s % (60 * 60)) / 60);
var seconds = Math.floor(s % 60);
console.log(days, hours, minutes, seconds);
$('.e-m-days', obj).html(days);
$('.e-m-hours', obj).html(hours);
$('.e-m-minutes', obj).html(minutes);
$('.e-m-seconds', obj).html(seconds);
}
var count = getCounterData($(".counter"));
var timer = setInterval(function() {
count--;
if (count == 0) {
clearInterval(timer);
return;
}
setCounterData(count, $(".counter"));
}, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="counter" style='color: green;'>
<span class='e-m-days'>0</span> Days |
<span class='e-m-hours'>8</span> Hours |
<span class='e-m-minutes'>0</span> Minutes |
<span class='e-m-seconds'>1</span> Seconds
</div>
Based on: https://www.w3schools.com/howto/howto_js_countdown.asp
I believe this is what you're looking for. I've added comments to show exactly what's happening. Please let me know if anything isn't clear. I just picked a random date as a target date, but you can change it to anything you want :)
$(document).ready(function() {
const days = $(".e-m-days");
const hours = $(".e-m-hours");
const minutes = $(".e-m-minutes");
const seconds = $(".e-m-seconds");
const targetDate = new Date('May 17, 2020 03:24:00');
function convertMillis(milliseconds, format) {
var days, hours, minutes, seconds, total_hours, total_minutes, total_seconds;
total_seconds = parseInt(Math.floor(milliseconds / 1000));
total_minutes = parseInt(Math.floor(total_seconds / 60));
total_hours = parseInt(Math.floor(total_minutes / 60));
days = parseInt(Math.floor(total_hours / 24));
seconds = parseInt(total_seconds % 60);
minutes = parseInt(total_minutes % 60);
hours = parseInt(total_hours % 24);
switch(format) {
case 's':
return total_seconds;
case 'm':
return total_minutes;
case 'h':
return total_hours;
case 'd':
return days;
default:
return { d: days, h: hours, m: minutes, s: seconds };
}
};
window.setInterval( function()
{
// Where we check if 'now' is greater than the target date
var date = Date.now();
if (date > targetDate)
{
// Where we break
console.log("Expired");
clearInterval();
} else
{
// Where we set values
var millis = targetDate - date;
var millisObject = convertMillis(millis);
// Display values in HTML
days.text(millisObject.d);
hours.text(millisObject.h);
minutes.text(millisObject.m);
seconds.text(millisObject.s);
};
}, 1000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span style='color: green;'>
<span class='e-m-days'>0</span> Days |
<span class='e-m-hours'>0</span> Hours |
<span class='e-m-minutes'>0</span> Minutes |
<span class='e-m-seconds'>0</span> Seconds
</span>
I want to implement a simple javascript countdown that always counts down to the user's local next Friday, 15:00. I currently use the following code, but I believe that it only displays the countdown to next Friday, 15:00 UTC. Any help would really be appreciated!!
var curday;
var secTime;
var ticker;
function getSeconds() {
var nowDate = new Date();
var dy = 5; //Sunday through Saturday, 0 to 6
var countertime = new Date(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate(), 15, 0, 0);
var curtime = nowDate.getTime(); //current time
var atime = countertime.getTime(); //countdown time
var diff = parseInt((atime - curtime) / 1000);
if (diff > 0) {
curday = dy - nowDate.getDay()
} else {
curday = dy - nowDate.getDay() - 1
} //after countdown time
if (curday < 0) {
curday += 7;
} //already after countdown time, switch to next week
if (diff <= 0) {
diff += (86400 * 7)
}
startTimer(diff);
}
function startTimer(secs) {
secTime = parseInt(secs);
ticker = setInterval("tick()", 1000);
tick(); //initial count display
}
function tick() {
var secs = secTime;
if (secs > 0) {
secTime--;
} else {
clearInterval(ticker);
getSeconds(); //start over
}
var days = Math.floor(secs / 86400);
secs %= 86400;
var hours = Math.floor(secs / 3600);
secs %= 3600;
var mins = Math.floor(secs / 60);
secs %= 60;
//update the time display
document.getElementById("days").innerHTML = curday;
document.getElementById("hours").innerHTML = ((hours < 10) ? "0" : "") + hours;
document.getElementById("minutes").innerHTML = ((mins < 10) ? "0" : "") + mins;
document.getElementById("seconds").innerHTML = ((secs < 10) ? "0" : "") + secs;
}
function starter() {
getSeconds();
}
Javascript dates are inherently UTC, however the various non–UTC get and set methods all work on local dates and times based on the host system clock and daylight saving settings.
So if you're not using UTC methods, everything in the OP is "local" by default. The following is a simplistic implementation of your "time until next Friday at 15:00" all as local values:
function timeUntil() {
let now = new Date();
// Create date for 15:00 on coming Friday
let friday = new Date(now);
friday.setHours(15,0,0,0);
let dayNum = friday.getDay();
friday.setDate(friday.getDate() + 5 - (dayNum < 6? dayNum : 5 - dayNum));
// If today is Friday and after 15:00, set to next Friday
if (dayNum == 5 && friday < now) {
friday.setDate(friday.getDate() + 7);
}
// Time remaining
let diff = friday - now;
let days = diff / 8.64e7 |0;
let hrs = (diff % 8.64e7) / 3.6e6 | 0;
let mins = (diff % 3.6e6) / 6e4 | 0;
let secs = (diff % 6e4) / 1e3 | 0;
// Display result
document.getElementById('days').textContent = days;
document.getElementById('hrs').textContent = hrs;
document.getElementById('mins').textContent = mins;
document.getElementById('secs').textContent = secs;
document.getElementById('fullDate').textContent = friday.toLocaleString();
}
setInterval(timeUntil, 1000);
td {
text-align: center;
}
<table>
<tr><th>Days<th>Hrs<th>Mins<th>Secs
<tr><td id="days"><td id="hrs"><td id="mins"><td id="secs">
<tr><td id="fullDate" colspan="4">
</table>
Note that setInterval isn't a good way to run a timer over a long period as it drifts (it doesn't run at exactly the specified interval). The overall time will be OK, it will just seem to skip from time to time and drift within a second with respect to the system displayed clock.
Better to use sequential calls setTimeout, calculating the time until just after the next full second each time so it closely matches the system clock's tick.
I want the time to always show 0's when less than 10 for example: if the task took 3 hours and 7 minutes and 33 seconds it would be displayed as 03:08
Right now I have the buttons disabled after they are clicked so that you cant restart the timer
Here is the JS code
let startTime;
const timer = typeof performance !== `undefined` && typeof performance.now === `function` ? performance : Date;
const startButton = document.getElementById('start');
const stopButton = document.getElementById('stop');
const display = document.getElementById('display');
startButton.onclick = () => {
console.debug('START')
startTime = timer.now();
startButton.disabled = "disabled";
};
stopButton.onclick = () => {
console.debug('STOP')
var totalSeconds = Math.round((timer.now() - startTime) / 1000);
var totalMinutes = Math.floor(totalSeconds / 60);
var totalHours = Math.floor(totalSeconds / 60 / 60);
var displaySeconds = totalSeconds - totalMinutes * 60;
var displayMinutes = totalMinutes - totalHours * 60;
var strDisplayTime =
(totalHours > 0 ? (totalHours + '0:') : '') +
(displayMinutes > 0 || totalHours > 00 ?
((displayMinutes >= 10 ? '' : '0') + displayMinutes + ':') : '00:00:') +
((displaySeconds >= 10 ? '' : '0') + displaySeconds)
display.innerHTML = strDisplayTime;
stopButton.disabled = "disabled";
};
Here is the HTML
<h1>
<!-- This shows the heading of the entire checklist -->
Master on Call Checklist
</h1>
<ul class="checklist ng-pristine ng-untouched ng-valid ng-isolate-scope ui-sortable" ui-sortable="sortableOptions" ng-model="task">
<li>
<h2>
<!-- This shows the heading of task that need to be constantly looked at -->
<a href="#">
Tasks that need to be constantly checked throughout the week
</a>
</h2>
</li>
<button type="button" id="start">Start Task</button>
<p style="float:left;"></p>
<!-- Heading to review cameras and adjest as needed -->
<a>
Review cameras and adjest as needed
</a>
<button type="button" id="stop">Finished Task</button>
<div id="display"></div>
You need to add +((timer.now() - startTime) / 1000 > 30) to totalMinutes and you need to calculate it mod 60. JSFiddle.
let startTime;
const timer = typeof performance !== `undefined` && typeof performance.now === `function` ? performance : Date;
const startButton = document.getElementById('start');
const stopButton = document.getElementById('stop');
const display = document.getElementById('display');
startButton.onclick = () => {
startTime = timer.now();
startButton.disabled = "disabled";
};
stopButton.onclick = () => {
var totalSeconds = Math.round((timer.now() - startTime) / 1000);
var totalMinutes = Math.floor(totalSeconds / 60 + +((timer.now() - startTime) / 1000 > 30));
var totalHours = Math.floor(totalSeconds / 60 / 60);
var displaySeconds = totalSeconds % 60;
var displayMinutes = totalMinutes % 60;
var strDisplayTime =
(totalHours > 0 ? (totalHours + '0:') : '') +
(displayMinutes > 0 || totalHours > 00 ?
((displayMinutes >= 10 ? '' : '0') + displayMinutes + ':') : '00:00:') +
((displaySeconds >= 10 ? '' : '0') + displaySeconds)
display.innerHTML = strDisplayTime;
stopButton.disabled = "disabled";
};
Try this one:
var fixedDisplaySeconds = ( '0' + displaySeconds ).substr( -2 );
var fixedDisplayMinutes = ( '0' + displayMinutes ).substr( -2 );
var fixedStrDisplayTime = fixedDisplaySeconds + ':' + fixedDisplayMinutes;
Basically, always add '0' at the beginning and then get the last 2 characters - if time was 1, then '0' + 1 = '01' - last 2 characters is '01'. Then if time is 11, '0' + 11 = '011' - get the last 2 characters and you get '11'.
You could create a Date directly from your millisecond counter and use the .getUTCHours() and getUTCMinutes() methods to format it as HH:MM.
// 3h07m33s in milliseconds
var ms = (3 * 3600 + 7 * 60 + 33) * 1000;
// create date (in the year 1970, which is OK)
var d = new Date(ms + 30000);
// format date as HH:MM
var strDisplayTime =
('0' + d.getUTCHours()).slice(-2) + ':' +
('0' + d.getUTCMinutes()).slice(-2);
console.log(strDisplayTime);
For browsers supporting it, you could also use .toLocaleString(). But it doesn't look like a very interesting option here.
// 3h07m33s in milliseconds
var ms = (3 * 3600 + 7 * 60 + 33) * 1000;
// create date (in the year 1970, which is OK)
var d = new Date(ms + 30000);
// format date as HH:MM
var strDisplayTime = d.toLocaleString(
'en-US',
{
timeZone: 'UTC', // we've created a UTC Date, so we must display it as such
hour12 : false, // use 24-hour format
hour : '2-digit', // display hours as two digits
minute : '2-digit' // display minutes as two digits
}
);
console.log(strDisplayTime);
Actually I have a date time or time-stamp format looks like 2015-12-18 07:10:54 this time should be converted or modified by like 2 hours ago or else.
I have tried this one. but there is something wrong with this.
Always showing 8 days ago. {which is wrong estimation.}
function ( date ) {
var seconds = Math.floor(( new Date() - date ) / 1000 );
var interval = Math.floor( seconds / 31536000 );
if ( interval == 1 ) {
return interval + " year ago";
}
if ( interval > 1 ) {
return interval + " years ago";
}
interval = Math.floor( seconds / 2592000 );
if ( interval == 1 ) {
return interval + " month ago";
}
if ( interval > 1 ) {
return interval + " months ago";
}
interval = Math.floor( seconds / 86400 );
if ( interval == 1 ) {
return interval + " day ago";
}
if ( interval > 1 ) {
return interval + " days ago";
}
interval = Math.floor( seconds / 3600 );
if ( interval == 1 ) {
return interval + " hour ago";
}
if ( interval > 1 ) {
return interval + " hours ago";
}
interval = Math.floor( seconds / 60 );
if ( interval == 1 ) {
return interval + " minute ago";
}
if ( interval > 1 ) {
return interval + " minutes ago";
}
return Math.floor(seconds) + " seconds ago";
}
I can suggest to use MomentJS that's a powerful library to manage dates, install it with :
npm install --save moment
And then you simply get the time from now as:
moment().fromNow();
Or
var yourDate = new Date();
moment(yourDate).fromNow();
Or as per your example:
moment("2015-12-18 07:10:54", "YYYY-MM-DD HH:mm:ss").fromNow();
If you have a date in ISO format like that below, you don't need to format it, just use it:
moment("2015-12-09T12:09:30.000Z").fromNow()
Using MomentJS this kind of operation become simple as:
moment().subtract(10, 'days').calendar(); // 12/08/2015
moment().subtract(6, 'days').calendar(); // Last Saturday at 10:10 AM
moment().subtract(3, 'days').calendar(); // Last Tuesday at 10:10 AM
moment().subtract(1, 'days').calendar(); // Yesterday at 10:10 AM
moment().calendar(); // Today at 10:10 AM
moment().add(1, 'days').calendar(); // Tomorrow at 10:10 AM
moment().add(3, 'days').calendar(); // Monday at 10:10 AM
moment().add(10, 'days'
this time should be converted or modified by like 2 hours ago or else
var result = document.querySelector('#result');
var dateFromString = new Date('2015-12-18 07:10:54');
result.textContent = 'dateFromString: ' + dateFromString;
// dateFromString: travel 2 hours back
dateFromString.setHours(dateFromString.getHours()-2);
result.textContent += '\n2 hours before 2015-12-18 07:10:54: ' +
dateFromString;
// determine difference between 2015-12-18 07:10:54 and the (time traveled) dateFromString
var difference = dateDiffCalc([new Date('2015-12-18 07:10:54'), dateFromString])
result.textContent += '\nHours difference dateFromString and '+
'2015-12-18 07:10:54: ' +
difference.hours;
function dateDiffCalc(value) {
var ms = Math.abs(value[0].getTime()-value[1].getTime());
var secsdf = Math.floor(((ms/1000)%(60*60))%60);
var mindf = Math.floor((ms/(60*1000))%60);
var hourdf = Math.floor(ms/(60*1000*60)%24);
var daydf = Math.round((ms/(60*1000*60))/24);
return {
days: daydf,
hours: hourdf,
minutes: mindf,
seconds: secsdf
};
}
<pre id="result"></pre>
As others have suggested, by using the Moment API you can achieve that very easily.
// Get the Time Since Content was Posted with Moment.js
const getDate = (date) => {
const dateTime = new Date(date * 1000);
return moment(dateTime).fromNow();
};
date is the UTC timestamp