I am weak on front end work and need a little help here.
I am developing a basic form that gives the users available schedule options for booking an appointment during the next 3 days inclusive.
So I have thus far written:
var today = new Date();
var lastday = new Date(today);
lastday.setDate(today.getDate() + 4);
var daterange = getAllDays(today, lastday);
function getAllDays(today, lastday)
{
var s = new Date(today);
var e = new Date(lastday);
var a = [];
//this gets my start time days
while (s < e)
{
//if day Saturday hours change
if(s.getDay() == 0)
{
//if Sunday skip
}
else if (s.getDay() == 6)
{
//push start onto array
a.push(setWorkingHours(s, '10'));
//push end onto array
a.push(setWorkingHours(s, '20'));
}
else
{
//push start onto array
a.push(setWorkingHours(s, '13'));
//push end onto array
a.push(setWorkingHours(s, '20'));
}
s = new Date(s.setDate(s.getDate() + 1))
}
return a;
};
function setWorkingHours(date, hour)
{
var dateTime = new Date();
dateTime.setDate(date.getDate());
dateTime.setHours(hour, '0', '0');
return dateTime;
}
alert(daterange.join('\n'));
Here is a fiddle.
Now this I know could use refinement and I am open to any improvements.
So the above code gets me an array of Days with a start and stop time. Now I'm struggling to figure out how I am going get an array of the hours within each days start and stop time.
Further once I have the hours I have a query to google calendar that returns events so I will then parse that into an array.
Upcoming events:
Bob Builder (2015-08-07T10:00:00-08:00)
John Doe (2015-08-08T11:00:00-08:00)
Mary Jane (2015-08-10T18:00:00-08:00)
Finally I will need to "intersect" the available array with the booked array and return what is left.
As for the appointments themselves. If a person picked a time I would then schedule a two hour block. Appointments can start at the top or bottom of the hour.
I would use something along the lines of the getTimeSlotsForDay function below to get an array of the available start times for a given day.
var GoogleCalenderAppointments = null;
var today = new Date();
var lastDay = new Date(today);
lastDay.setDate(today.getDate() + 4);
function checkGoogleCalendarConflict(date) {
var hasConflict = false;
if (!GoogleCalenderAppointments) {
//logic to get scheduled appointments
}
//iterate through relevant scheduled appointments
//if argument `date` has conflict, return true
//else, return false
return hasConflict
}
function getTimeSlotsForDay(date) {
var timeSlots = []
var dayStart = new Date(date)
var dayEnd = new Date(date)
switch (date.getDay()) {
case 0: //Sunday
return timeSlots;
case 6: //Saturday
dayStart.setHours(10, 0, 0, 0)
dayEnd.setHours(20, 0, 0, 0)
break;
default:
dayStart.setHours(13, 0, 0, 0)
dayEnd.setHours(20, 0, 0, 0)
}
do {
if (!checkGoogleCalendarConflict(dayStart)) {
timeSlots.push(new Date(dayStart))
}
dayStart.setHours(dayStart.getHours(), dayStart.getMinutes() + 30)
} while (dayStart < dayEnd);
return timeSlots
}
var message = ""
for (var i = new Date(today); i < lastDay; i.setDate(i.getDate() + 1)) {
message += i.toDateString() + ":\n"
message += getTimeSlotsForDay(i).map(function(it) {
return it.toTimeString();
}).join(",\n") + "\n";
}
alert(message)
Referring to your array issue make an object of day arrays. Import momentjs. Make a two item array of start and end. Their date object is more full and they have great functions to check out.
Calendar = {
January-1: [[new Date(), new Date() ], [new Date(), new Date() ]]
}
For the second part underscorejs is nice. Use _.zip(array, array). (you will need to format the Google array to match your array).
Related
I have the weekday value (0-6 for Sun-Sat)...how do I get an array of days (starting on Sunday for the given week?
Here is what I'm trying to do:
A user clicks a day (ie: May 10) and it generates an array of the dates for the current week:
function selectWeek(date) {
selectedWeek = [];
let d = new Date(date.key);
console.log(d);
console.log(date.weekday, 'weekday');
console.log(date);
for (let i = 0; i < date.weekday; i++) {
console.log(i, 'pre');
let currD = d.setDate(d.getDate() - i).toString();
console.log(currD);
selectedWeek.push(currD);
}
for (let i = date.weekday; i < 7; i++) {
console.log(i, 'post');
selectedWeek.push(d.setDate(d.getDate() + i).toString());
}
console.log(selectedWeek);
}
I need Sunday through Saturday date objects.
I am not using a date library so prefer vanilla javascript solutions.
Create an array with 7 elements, subtract the weekday and add the index as day:
function selectWeek(date) {
return Array(7).fill(new Date(date)).map((el, idx) =>
new Date(el.setDate(el.getDate() - el.getDay() + idx)))
}
const date = new Date();
console.log(selectWeek(date));
I'm using
fill(new Date(date))
to create a copy and not modify the argument.
You can get the days of a month with the same concept:
function selectMonth(date) {
return Array(31).fill(new Date(date)).map((el, idx) =>
new Date(el.setDate(1 + idx))).filter(el => el.getMonth() === date.getMonth());
}
const date = new Date();
console.log(selectMonth(date));
here's how I would solve this one:
function selectWeek(date) {
let selectWeek = [];
for (let i=0; i<7; i++) {
let weekday = new Date(date) // clone the selected date, so we don't mutate it accidentally.
let selectedWeekdayIndex = date.getDay() // i.e. 5 for friday
let selectedDay = date.getDate() // 1-31, depending on the date
weekday.setDate(selectedDay - selectedWeekdayIndex + i)
selectWeek = [...selectWeek, weekday]
}
return selectWeek;
}
Let's take today's date as an example: 18.02.22. Friday.
We do 6 iterations. On first one we get the selectedWeekdayIndex, which is 5 for friday. We clone the date and re-set it's day (18) reducing it by this number: 18-5 = 13. This is the day for Sunday. Then we go on incrementing days by one to fill the rest of the week.
Of course it can be optimised and written much shorter, but I tried to show and explain the logic.
The .getDay() gives you the day of the week.
function selectWeek(date) {
const selectWeek = [];
let temp = date;
while (temp.getDay() > 0) temp.setDate(temp.getDate() - 1); // find Sunday
// get the rest of the week in the only do while loop ever created
do {
selectWeek.push(new Date(temp));
temp.setDate(temp.getDate() + 1);
} while (temp.getDay() !== 0);
return selectWeek;
/* for display purposes only */
// const dates = selectWeek.map((date) => date.toString());
// console.log(dates);
}
selectWeek(new Date());
selectWeek(new Date("2020-01-01"));
selectWeek(new Date("december 25, 1990"));
Did you check Date prototypes before?
I think Date.prototype.getDay() can do what you want:
function selectWeekDays(date) {
var i,
d = new Date(date),
a = [];
// console.log(d.getDay()); // Number of the day
d.setDate(d.getDate() - d.getDay() - 1); // Set date one day before first day of week
for (i=0; i<7; i++) {
d.setDate(d.getDate() + 1); // Add one day
a.push(d.valueOf());
}
return a;
}
var result = selectWeekDays('2022-01-01') // Satureday = 6
console.log(result);
result.forEach(e => console.log(new Date(e).toString()));
Here's the code I'm working on:
function populateDates() {
var start = new Date(2017, 7, 13);
var end = new Date(2017, 8, 3);
var tempDate = start;
var endPlus90 = end.setDate(end.getDate() + 90);
var today = new Date();
var array = [];
for(var d = start; d < today || d < endPlus90; d.setDate(d.getDate() + 1)){
if (d.getDay() !== 0 && d.getDay() !== 6){
array.push([d]);
}
}
return array;
}
var future = new Date();
future.setDate(future.getDate() + 90);
console.log(populateDates(new Date(), future));
Basically, what I'm trying to do is, given an arbitrary start and end date, generate a list of dates, excluding weekends, from the start date to either 90 days after the end date, or the current date, whichever is earlier. The current function generates an array that is all identical dates which are 90 days after the end date. I'm not very familiar with Javascript, so I'm not sure what's going wrong here. I suspect that the way I'm pushing the variable to the array is incorrect.
The problem comes with your usage of setDate which returns
The number of milliseconds between 1 January 1970 00:00:00 UTC and the given date (the Date object is also changed in place).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate
Wrap that setDate line in a new Date() and your code should run just fine.
As others pointed out the reason the array had multiples of the same date is because you were pushing references to the same single date object, and reassigning that object's date, which was updating it each of these references. By creating a new Date with new Date() you are creating a new object with its own reference.
Try this out. You need to initialize the d to a new Date every time. You can't just change the day. You also need to put new Date() around end.setDate(). setDate() returns milliseconds.
function populateDates(start, end) {
var tempDate = start;
var endPlus90 = new Date(end.setDate(end.getDate() + 90));
var today = new Date();
var array = [];
for(var d = tempDate; d < endPlus90; d = new Date(d.setDate(d.getDate() + 1))){
if(d >= today) { // Stop counting dates if we reach the current date
break;
}
if (d.getDay() !== 0 && d.getDay() !== 6){
array.push([d]);
}
}
return array;
}
var future = new Date(); // As of 10/18/2017
future.setDate(future.getDate() + 90);
console.log(populateDates(new Date(2017, 9, 1), future)); // Prints 13 days as of 10/18/2017
console.log(populateDates(new Date(2016, 9, 1), future)); // Prints 273 days
I'm facing issue with excluding weekend dates in JavaScript.For my business requirement I want to exclude 3 days from date object Friday, Saturday and Sunday in every week.What I need here is the values of Friday should display as Monday, Saturday as Tuesday and Sunday as Wednesday. I'm able to do this.
The issue that I'm facing here is when we run the above example the a[0] value should be 21-SEP-2017 but I'm getting 20-SEP-2017 and remaining array values should not change. So please do help me out in resolving this issue
var a = ["21-SEP-2017", "22-SEP-2017", "23-SEP-2017", "24-SEP-2017", "25-SEP-2017"];
for (i = 0; i < a.length; i++) {
var startDate = a[i];
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "",
noOfDaysToAdd = 1;
var count = 0;
endDate = new Date(startDate.setDate(startDate.getDate()));
if (startDate.getDay() != 0 && startDate.getDay() != 5 && startDate.getDay() != 6) {
endDate = new Date(startDate.setDate(startDate.getDate() + i - 1));
} else {
startDate.setDate(startDate.getDate() + 3)
endDate = new Date(startDate.setDate(startDate.getDate()));
}
console.log(endDate); //You can format this date as per your requirement
}
Your code seems not finished: the variables noOfDaysToAdd and count are never used, and if they were, they would be reset in every iteration of the loop, which cannot be the purpose.
That your output shows 20 September is because you did not output a stringified version of the date, but the date object itself, and then console.log will display the date as a UTC date (notice the time part matches the timezone difference). Instead use .toString() or another way to turn the date to a localised string.
Here is how you could do it:
function toDate(s) {
return new Date(s.replace(/-/g, '/'));
}
function toStr(dt) {
var months = ["JAN","FEB","MAR","APR","MAY","JUN",
"JUL","AUG","SEP","OCT","NOV","DEC"];
return [('0'+dt.getDate()).substr(-2), months[dt.getMonth()], dt.getFullYear()]
.join('-');
}
var a = ["21-SEP-2017", "22-SEP-2017", "23-SEP-2017", "24-SEP-2017", "25-SEP-2017"],
add = 0;
var result = a.map(toDate).map(dt => {
dt.setDate(dt.getDate()+add);
var move = [0, 6, 5].indexOf(dt.getDay()) + 1;
if (move) {
add += move;
dt.setDate(dt.getDate()+move);
}
return dt;
}).map(toStr);
console.log(result);
I have been working on a script that dynamically creates a date/time value between two days. However I want to limit it as follows:
if appointment.status === "today": Set the range between now (start) and the end of the working day (end) i.e. today between time right now to 18:00
if appointment.status === "pending": Set the range from tomorrow (start) + 1 week (end) but keeping in mind the working day i.e. 08:00-17:00... so it can be next week Tuesday 13:00
Once done, I would like to convert var date to a timestamp.
This is my code so far:
if (appointment.status === "today") {
appointment.timestamp = (function() {
var a = randomTime(new Date("10-10-2015 10:30"), new Date("12-10-2015 02:10"));
return a
})();
} else if (appointment.status === "pending") {
appointment.timestamp = (function() {
var a = randomTime(new Date("10-10-2015 10:30"), new Date("12-10-2015 02:10"));
return a
})();
}
function randomTime(start, end) {
var diff = end.getTime() - start.getTime();
var new_diff = diff * Math.random();
var date = new Date(start.getTime() + new_diff);
return date;
}
var start = new Date();
var end = new Date();
if (appointment.status === "today") {
end.setHours(18);
end.setMinutes(0);
} else if (appointment.status === "pending") {
start.setDate(start.getDate() + 1);
end.setDate(end.getDate() + 7);
}
start = restrictTimeToWorkHours(start);
end = restrictTimeToWorkHours(end);
appointment.timestamp = Math.floor(randomTime(start, end) / 1000);
function randomTime(start, end) {
var diff = end.getTime() - start.getTime();
var new_diff = diff * Math.random();
return new Date(start.getTime() + new_diff);
}
function restrictTimeToWorkHours(date) {
if (date.getHours() < 8) {
date.setHours(8);
date.setMinutes(0);
}
if (date.getHours() > 16) {
date.setHours(16);
date.setMinutes(0);
}
return date;
}
The key thing to remember here is the Math.floor(randomTime(start, end) / 1000);. You said you wanted it in timestamp, so I take it to mean you want a Unix Timestamp. A Unix Timestasmp is in seconds, while Date.getTime() is in milliseconds, so we need to divide by 1000 to get seconds
Either look for a date library or create your own date transformation function for each operation and combine those.
endOfDay(time)
getRandomTimeBetween(startTime, endOfDay(startTime))
isWorkingDay(time)
// etc.
For the second case, you can do it in two steps: select a random day in the range, then select a random time within the working hours of that day.
Break it down to simple, logical operations, and you can test each function separately, and your code will look nice and readable.
Hi i am trying to do a IF statement which allows the current date to be compared to the input date.. if the input date is below the current date it will be false.
I have got the date passing through my variable but it only stores the number so for example it compares day 9 to another day, which is not very reliable. I want the variable to take in the month and the year as well, meaning it can compare the ENTIRE DATE.
If there is a better way let me know.
Here is my code
if (this.element.find('#visitdate').length > 0) {
var dateParts = $('#visitdate').val().split('/');
var check = new Date(dateParts[2], dateParts[1], dateParts[0], 0,0,0,0).getDate();
var today = new Date().getDate;
if (check < today) {
_errMsg = "Please enter a furture visit date";
return false;
} else {
return true;
}
}
Your line for today's date contains an error:
var today = new Date().getDate;
should be
var today = new Date().getDate();
format as mm/dd/yyyy
var from = '08/19/2013 00:00'
var to = '08/12/2013 00:00 '
var today = new Date().getDate();
function isFromBiggerThanTo(dtmfrom, dtmto){
var from = new Date(dtmfrom).getTime();
var to = new Date(dtmto).getTime() ;
return from >= to ;
}
or using below
var x = new Date('2013-05-23');
var y = new Date('2013-05-23');
and compare
You can try this - it's working fine in my project -
Step 1
First Create javascript function as below.
Date.prototype.DaysBetween = function () {
var intMilDay = 24 * 60 * 60 * 1000;
var intMilDif = arguments[0] - this;
var intDays = Math.floor(intMilDif / intMilDay);
if (intDays.toLocaleString() == "NaN") {
return 0;
}
else {
return intDays + 1;
}
}
Step 2
-
var check = new Date(dateParts[2], dateParts[1], dateParts[0], 0,0,0,0).getDate();
var today = new Date().getDate;
var dateDiff = check .DaysBetween(today);
// it will return integer value (difference between two dates )
if(dateDiff > 0 ){ alert('Your message.......');}
You can have this much easier.
You dont need to check with getDate() property you can just compare 2 dates.
And also is not needed to initialize with hours, minutes and seconds the Date, you only need year, month and date.
Here you have your example simplified
var dateParts = $('#visitdate').val().split('/');
var check = new Date(dateParts[2], dateParts[1], dateParts[0]);
var today = new Date();
if (check < today) {
return false;
} else {
return true;
}
http://jsfiddle.net/wns3LkLv/
Try this:
var user="09/09/2014/5/30";
var arrdt= user.split("/");
var userdt = new Date(arrdt[2], arrdt[1] - 1, arrdt[0],arrdt[3],arrdt[4]);
var currdt = new Date();
if (userdt < currdt) {
alert("userdate is before current date"); //do something
}else{
alert("userdate is after current date"); //do something
}
Thanks for all your answers guys i have fixed it.
I used the getTime function instead of getDate.
Then the check variable had to have a -1 assigned to the month as it was going 1 month to high.
var check = new Date(dateParts[2], dateParts[1]-1, dateParts[0], 0,0,0,0).getTime();
Cheers