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>
I have some string like
ex. '8:00 AM' '12:00 PM' '2:00 PM'
how can I check in javascript or jquery to see if this time is past the current time?
Here is what I've tried so far but the isAfter method doesn't seem to work
var time = moment(startTime, 'HH:mm A'); //.format('HH:mm A');
if (time.isAfter(moment())) {
yb.base.eventAlert("You can't create events in the past! Try refreshing your page", "info");
return false;
}
UPDATE - I figured it out!
I had to use 'hour minute' as a condition
if (moment().isAfter(time, 'hour minute')) {
yb.base.eventAlert("You can't create events in the past! Try refreshing your page", "info");
return false;
}
Try this function :
function checktime() {
var dt = new Date(); //Get current time
var time = dt.getHours() + ":" + dt.getMinutes(); //Get hour and minutes
var timeStr = document.getElementById('time').value; // Get string time
var parts = timeStr.split(':'); // Split string to get hours and minutes
var hour = parseInt($.trim(parts[0]));
// swap am & pm
if (parts[1].match(/(AM|am)/)) {
if (hour == 12) {
// easily flip it by adding 12
hour = 0;
}
parts[1] = parseInt(parts[1])
} else {
if (hour < 0) {
hour = hour + 12
}
parts[1] = parseInt(parts[1]);
}
timeStr = hour + ':' + parts[1];
if (hour > dt.getHours() && parts[1] > dt.getMinutes) {
console.log("Past time");
console.log(hour + " " + dt.getHours());
} else if (hour == dt.getHours() && parts[1] > dt.getMinutes) {
console.log("Past time");
console.log(hour + " " + dt.getHours());
} else {
console.log("Not Past time");
console.log(hour + " " + dt.getHours());
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="time" placeholder="Insert time" />
<button onclick="checktime();">Check time</button>
This solved it
if (moment().isAfter(time, 'hour minute')) {
yb.base.eventAlert("You can't create events in the past! Try refreshing your page", "info");
return false;
}
function isPastCurrentTime (time){
let timeNow = new Date();
//converts timeNow to just the date string
let date = timeNow.toLocaleDateString();
//adds the time to check to the date string, converts it to milliseconds
//then truncates the last four digits to compare minutes
//instead of milliseconds
let timeToCheck = Math.floor(new Date(date + ' ' + time).getTime() / 60000);
//converts timeNow to milliseconds, then truncates the last four digits
//to compare minutes instead of milliseconds
let currentTime = Math.floor(timeNow.getTime() / 60000);
return timeToCheck > currentTime;
}
I was on the lookout for a javascript countdown with adjustable timezones, and found this script called tzcount.js. According to the instructions:
The month can be specified as a number between 1 and 12 to indicate
which month of the year that you are counting down to (it will assume
next year if the month has already past for this year)
But when I enter the value 1 for month, the script tells me that the date has passed, instead of assuming it is the first month of the next year. Am I missing something or is this script not working as intended?
The full script:
<!--Copy and paste just above the close </BODY> of you HTML webpage.-->
<SCRIPT type="text/javascript">
// **** Time Zone Count Down Javascript **** //
/*
Visit http://rainbow.arch.scriptmania.com/scripts/
for this script and many more
*/
////////// CONFIGURE THE COUNTDOWN SCRIPT HERE //////////////////
var month = '*'; // '*' for next month, '0' for this month or 1 through 12 for the month
var day = '1'; // Offset for day of month day or + day
var hour = 0; // 0 through 23 for the hours of the day
var tz = -5; // Offset for your timezone in hours from UTC
var lab = 'tzcd'; // The id of the page entry where the timezone countdown is to show
function start() {displayTZCountDown(setTZCountDown(month,day,hour,tz),lab);}
// ** The start function can be changed if required **
window.onload = start;
////////// DO NOT EDIT PAST THIS LINE //////////////////
function setTZCountDown(month,day,hour,tz)
{
var toDate = new Date();
if (month == '*')toDate.setMonth(toDate.getMonth() + 1);
else if (month > 0)
{
if (month <= toDate.getMonth())toDate.setYear(toDate.getYear() + 1);
toDate.setMonth(month-1);
}
if (day.substr(0,1) == '+')
{var day1 = parseInt(day.substr(1));
toDate.setDate(toDate.getDate()+day1);
}
else{toDate.setDate(day);
}
toDate.setHours(hour);
toDate.setMinutes(0-(tz*60));
toDate.setSeconds(0);
var fromDate = new Date();
fromDate.setMinutes(fromDate.getMinutes() + fromDate.getTimezoneOffset());
var diffDate = new Date(0);
diffDate.setMilliseconds(toDate - fromDate);
return Math.floor(diffDate.valueOf()/1000);
}
function displayTZCountDown(countdown,tzcd)
{
if (countdown < 0) document.getElementById(tzcd).innerHTML = "Sorry, you are too late.";
else {var secs = countdown % 60;
if (secs < 10) secs = '0'+secs;
var countdown1 = (countdown - secs) / 60;
var mins = countdown1 % 60;
if (mins < 10) mins = '0'+mins;
countdown1 = (countdown1 - mins) / 60;
var hours = countdown1 % 24;
var days = (countdown1 - hours) / 24;
document.getElementById(tzcd).innerHTML = days + " day" + (days == 1 ? '' : 's') + ' + ' +hours+ 'h : ' +mins+ 'm : '+secs+'s';
setTimeout('displayTZCountDown('+(countdown-1)+',\''+tzcd+'\');',999);
}
}
</SCRIPT>
<p><font face="arial" size="-2">The countdown script at </font><br><font face="arial, helvetica" size="-2">Rainbow Arch</font></p>
I found the script, and the instructions, here http://rainbow.arch.scriptmania.com/scripts/timezone_countdown.html
The script isn't working right.
You need to edit this line:
if (month <= toDate.getMonth())toDate.setYear(toDate.getYear() + 1);
getYear abbreviates, so it returns 115 for this year. setYear then thinks you mean 115 AD, which passed a long time ago.
Replace setYear and getYear with setFullYear and getFullYear. Those functions will return/expect 2015.
I'm making a javascript counter that counts 'seconds ago'. I have my time in a JS time object, and I found a "time difference" function snippet here on stack overflow, but it displays "2 hours ago". How can I get it to display "5 hours, 10 minutes and 37 seconds ago."
Here's what I'm working with:
This function converts the current time and the timestamp of something into "20 seconds ago" instead of a cryptic date:
function timeDifference(current, previous) {
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;
var elapsed = current - previous;
if (elapsed < msPerMinute) {
return Math.round(elapsed/1000) + ' seconds ago';
} else if (elapsed < msPerHour) {
return Math.round(elapsed/msPerMinute) + ' minutes ago';
} else if (elapsed < msPerDay ) {
return Math.round(elapsed/msPerHour ) + ' hours ago';
} else if (elapsed < msPerMonth) {
return 'approximately ' + Math.round(elapsed/msPerDay) + ' days ago';
} else if (elapsed < msPerYear) {
return 'approximately ' + Math.round(elapsed/msPerMonth) + ' months ago';
} else {
return 'approximately ' + Math.round(elapsed/msPerYear ) + ' years ago';
}
}
And here's what I'm using to "count up" the time each second. I'd like it to say "5 hours, 3 minutes, 10 seconds ago" and then 1 second later, "5 hours, 3 minutes, 11 seconds ago"
var newTime = new Date(data.popular[i].timestamp*1000)
var relTime = timeDifference(new Date(),newTime)
setInterval(function(){
var theTimeEl = $('.timestamp-large').filter(function(){
return $(this).html() == relTime
});
newTime.setSeconds(newTime.getSeconds() + 1);
var relTime = timeDifference(new Date(), newTime);
$(theTimeEl).html(relTime);
console.log(relTime)
}, 1000)
The variable newTime is the time in the UTC javascript date format. relTime is that in "seconds ago" format. The interval loops through a bunch of timestamp elements and picks the right one for each time stamp. Then it adds a second to the time, converts it back into "fuzzy time" (seconds ago), replaces the html with the new time and logs it in the console.
How do I change "5 hours ago" to "5 hours, 37 mintues, 10 seconds ago"? The time difference function needs to be modified.
Here's a function that is close to what you're asking for.
var timeparts = [
{name: 'year', div: 31536000000, mod: 10000},
{name: 'day', div: 86400000, mod: 365},
{name: 'hour', div: 3600000, mod: 24},
{name: 'minute', div: 60000, mod: 60},
{name: 'second', div: 1000, mod: 60}
];
function timeAgoNaive(comparisonDate) {
var
i = 0,
l = timeparts.length,
calc,
values = [],
interval = new Date().getTime() - comparisonDate.getTime();
while (i < l) {
calc = Math.floor(interval / timeparts[i].div) % timeparts[i].mod;
if (calc) {
values.push(calc + ' ' + timeparts[i].name + (calc != 1 ? 's' : ''));
}
i += 1;
}
if (values.length === 0) { values.push('0 seconds'); }
return values.join(', ') + ' ago';
}
console.log(timeAgoNaive(new Date(Date.parse('Jun 12 2006 11:52:33'))));
console.log(timeAgoNaive(new Date(new Date().getTime() - 3600000)));
console.log(timeAgoNaive(new Date()));
Results:
6 years, 33 days, 4 hours, 52 minutes, 22 seconds ago
1 hour ago
0 seconds ago
I called it "naive" because it doesn't really pay attention to the human way that we calculate time. If it is "1/1/2013 12:01:00 am" exactly, comparing to "1/1/2012 12:01:00 am" should yield "1 year, 0 months, 0 days, 0 hours, 0 minutes, 0 seconds ago". But it won't do that by extending the logic in the function you presented, and it won't do that in my function either (plus my function won't use months). A better approximation of years than 365 days is 365.24, but that also is ignored.
I excluded the empty time parts as you requested, leaving "0 seconds" at a minimum when there are no time parts found.
Now, if you want that human-like way of calculating, you have to decide some things. You can't just use boundaries crossed because Feb 28 to Mar 1 is not a whole month. Second, here's a question will expose the real problem:
How many months and days is Feb 2 to Mar 31?
If you calculate Feb 2 to Mar 2 as one month, then it's 1 month 29 days. But what if it were Jan 2 to Mar 1? That's the same number of days elapsed between them. Is that now 1 month (for all of April) + 1 day in March + the 31 days in Jan for 1 month 32 days? Do you want your months to coincide to a physical calendar so a human could back track with his finger and get the correct date out of it? That is much harder than you think.
If you can answer with sensible and complete rules about how you would do "human-like elapsed time figuring" then maybe I can write you another function to do it.
Update
Here's a new function that does months, and has 365.24 days in a year (30.43666666 days in a month):
var timeparts = [
{name: 'millenni', div: 31556736000, p: 'a', s: 'um'},
{name: 'centur', div: 3155673600, p: 'ies', s: 'y'},
{name: 'decade', div: 315567360},
{name: 'year', div: 31556736},
{name: 'month', div: 2629728},
{name: 'day', div: 86400},
{name: 'hour', div: 3600},
{name: 'minute', div: 60},
{name: 'second', div: 1}
];
function timeAgoNaive2(comparisonDate) {
var i = 0,
parts = [],
interval = Math.floor((new Date().getTime() - comparisonDate.getTime()) / 1000);
for ( ; interval > 0; i += 1) {
var value = Math.floor(interval / timeparts[i].div);
interval = interval - (value * timeparts[i].div);
if (value) {
parts.push(value + ' ' + timeparts[i].name + (value !== 1 ? timeparts[i].p || 's' : timeparts[i].s || ''));
}
}
if (parts.length === 0) { return 'now'; }
return parts.join(', ') + ' ago';
}
console.log(timeAgoNaive2(new Date(Date.parse('Jun 12 2006 11:52:33'))));
console.log(timeAgoNaive2(new Date(new Date().getTime() - 3600000)));
console.log(timeAgoNaive2(new Date()));
console.log(timeAgoNaive2(new Date(-92709631247000)));
Output:
6 years, 1 month, 1 day, 10 hours, 53 minutes, 44 seconds ago
1 hour ago
now
2 millennia, 9 centuries, 8 decades, 4 months, 26 days, 22 hours, 41 minutes, 47 seconds ago
It is still naive, but it does a little better job. Plus it will work for REALLY old dates like B.C. ones. :)
Change the logic so that rather than just finding the single greatest unit of measurement it can, it does something with the remainder.
Basically what you'd need to do is start with the greatest increment, find the value, then subtract it from the total to get the remainder. Then repeat.
Something like this maybe, I haven't tested it.
var elapsed = current - previous;
var remainder = elapsed;
int years;
int months;
years = Math.floor(remainder/msPerYear);
remainder = remainder % msPerYear;
months = Math.floor(remainder/msPerMonth);
remainder = remainder % msPerMonth;
// repeat
Then just build your string off the variables.
This should do the trick:
var msPerMinute = 60 * 1000;
var msPerHour = msPerMinute * 60;
var msPerDay = msPerHour * 24;
var msPerMonth = msPerDay * 30;
var msPerYear = msPerDay * 365;
function timeDifference(current, previous) {
var remainder = current - previous;
var message = "";
var sep = "";
var years = Math.floor(remainder/msPerYear);
remainder = remainder - years * msPerYear;
if (years > 0) {
message += years + " years";
sep = ", ";
console.log(message);
}
var months = Math.floor(remainder/msPerMonth);
remainder = remainder - months * msPerMonth;
if (months > 0) {
message += sep + months + " months";
sep = ", ";
console.log(message);
}
var days = Math.floor(remainder/msPerDay);
remainder = remainder - days * msPerDay;
if (days > 0) {
message += sep + days + " days";
sep = ", ";
console.log(message);
}
var hours = Math.floor(remainder/msPerHour);
remainder = remainder - hours * msPerHour;
if (hours > 0) {
message += sep + hours + " hours";
sep = ", ";
console.log(message);
}
var minutes = Math.floor(remainder/msPerMinute);
remainder = remainder - minutes * msPerMinute;
if (months > 0) {
message += sep + minutes + " minutes";
sep = ", ";
console.log(message);
}
var seconds = Math.floor(remainder/1000);
remainder = remainder - seconds * 1000;
if (months > 0) {
message += sep + seconds + " seconds";
sep = ", ";
console.log(message);
}
message += " ago";
var pos = message.lastIndexOf(',');
message = message.substring(0,pos) + ' and' + message.substring(pos+1)
return message;
};
var output = timeDifference(new Date(2012, 10, 20, 12, 0, 59), new Date(2012, 2, 13, 10, 15, 12));
console.log(output);
Output: 8 months, 12 days, 1 hours, 45 minutes and 47 seconds ago
This could of course be refactored to be a bit less repetitive.
You can try out this fiddle with it working: http://jsfiddle.net/vawEf/
So here is my goal, I want to get how long ago a certain date was as a pretty readable string. Something like: '4 day and 3 hours ago'. I am using datejs and have both my dates currently as epochs.
I know I could subtract one epoch from the other, take the difference and then manually calculate the string to output. But this feels like something datejs would handle. However I see no documentation (of any js lib for that matter) expressing a means of converting a date object, or an epoch to a quantity of time.
any ideas, on how this best should be handled?
UPDATE
Let me be more clear. When I say human readable that means
1 day ago is 'yesterday'
2 days ago is '2 days ago'
30 seconds ago is 'just now'
1 year and 3 days and 12 seconds ago is '1 year ago'
What I ended up doing
prettyAgo = (ago) ->
ago = ago.getTime() if typeof ago is 'object'
diff = ((new Date()).getTime() - ago) / 1000
dayDiff = Math.floor(diff / 86400)
return false if isNaN(dayDiff) or dayDiff < 0
writer = ''
if dayDiff is 0
if diff < 1 then writer = 'just now'
else if diff < 60 then writer = Math.floor(diff)+' seconds ago'
else if diff < 120 then writer = '1 minute ago'
else if diff < 3600 then writer = Math.floor(diff / 60)+' minutes ago'
else if diff < 7200 then writer = '1 hour ago'
else if diff < 86400 then writer = Math.floor(diff / 3600)+' hours ago'
else if dayDiff is 1 then writer = 'yesterday'
else if dayDiff < 7 then writer = dayDiff+' days ago'
else if dayDiff is 7 then writer = '1 week ago'
else if dayDiff < 31 then writer = Math.ceil( dayDiff / 7 )+' weeks ago'
else writer = new Date(ago).toString 'MMM yyyy'
return writer
DateJS does handle this by including a class called TimeSpan (defined in time.js, not in the base JS file) which does the calculations for you. It doesn't do the formatting, so you'd need something like this:
function showDiff(date1, date2) {
var diff, rv, yrs;
diff = new TimeSpan(date2 - date1);
if (diff.days > 0) {
// A day or more difference
if (diff.days === 1) {
rv = "yesterday";
}
else if (diff.days >= 365) {
yrs = diff.days / 365;
if (yrs === 1) {
rv = "1 year ago";
}
else {
rv = yrs + " years ago";
}
}
else {
rv = diff.days + " ago";
}
}
else {
// Less than 1 day difference
if (diff.hours > 0) {
if (diff.hours === 1) {
rv = "1 hour ago";
}
else {
rv = diff.hours + " hours ago";
}
}
else if (diff.minutes > 0) {
if (diff.minutes === 1) {
rv = "1 minute ago";
}
else {
rv = diff.minutes + " minutes ago";
}
}
else {
rv = "just now";
}
return rv;
}
Obviously this isn't perfect and doesn't handle leap years and all that, but it should give you the idea.
Actually you can do that in pure JavaScript.
function format(num) {
var date = new Date(num),
time = [];
with(time) {
push(date.getUTCDate() - 1);
push(date.getUTCHours());
push(date.getUTCMinutes());
push(date.getUTCSeconds());
}
if (time[0] > 29) {
time[0] = Math.floor(date / 86400000);
}
return time[0] + " day " + time[1] + " hours " + time[2] + " mintues " + time[3] + " seconds ago";
}
http://jsfiddle.net/DerekL/NqTnF/