Javascript dates to array - javascript

I am working on a website where users can book vacation houses.
Booking always is from Saturday to Saturday. If users click on any date in that week, the whole week must be selected. I've got that part working.
I gave the selected dates the "date-range-selected" class. And if the first day was already booked, but only in the morning then I gave it the class "half-selected". Now because I need to calculate with these dates I need the full dates and not only the day number. Only the ones with the "half-selected" and the "date-range-selected" need to be added to an array.
I tried to push variables to that array and it seemed to work, but when I try to use the array after the for loop, it seems like all array content is changed to the date after the last selected date, what am I doing wrong?
//ex.selected dates are: 9-16 august
var halfke= document.getElementsByClassName("half-selected");
var rest = document.getElementsByClassName("date-range-selected");
var dagen = [];
if(typeof halfke[0] != 'undefined')
{
dagen.push(halfke[0].getElementsByClassName("ui-state-default")[0].innerHTML.trim());
}
for (index = 0; index < rest.length; ++index)
{
dagen.push(rest[index].getElementsByClassName("ui-state-default")[0].innerHTML.trim());
}
var myDate = new Date(cur);
var dw = myDate.getDay();
myDate.setDate(myDate.getDate() - (dw+1));
var myDate2 = new Date(cur);
myDate2.setDate(myDate2.getDate() + (6-dw));
//alert(dagen[0]);
var juiste_dagen = new Array();
for (var d = myDate; d <= myDate2; d.setDate(d.getDate() + 1)) {
//alert(dagen[0]+ " - " + String(d.getDate()))
if(dagen.indexOf(String(d.getDate()))>-1)
{
//alert(d);
juiste_dagen.push(d);
alert(juiste_dagen[0]);//here it alerts 9 august (as it should)
}
}
alert("done");
alert(juiste_dagen[0]);//here it alerts 17 august(which it should not do)
alert(juiste_dagen[1]);//here it alerts 17 august(which it should not do)
alert(juiste_dagen[2]);//here it alerts 17 august(which it should not do)
It's probably something small and stupid but I can't seem to find it.
Any help is appreciated!

This is a pass-by-reference problem and it's working as intended. Primitives (like numbers and strings) are pass-by-value. Date is an object, and it is passed by reference, which means without copying. Everywhere you pass a Date object is the same date. Look at the following code, tested just now in my Chrome console:
var myDate = new Date();
undefined
var juiste_dagen = [];
undefined
juiste_dagen.push(myDate);
1
juiste_dagen[0];
Fri Jul 18 2014 09:35:02 GMT-0500 (CDT)
myDate.setDate(19);
1405780502241
juiste_dagen[0];
Sat Jul 19 2014 09:35:02 GMT-0500 (CDT)
So the problem is in your last forloop where you do d.setDate(d.getDate() + 1). You're essentially setting all of the dates pushed into your array to this date on every iteration of the loop. Either use a simple number for a loop counter or create a new date each time before changing the day.

Related

Angular Date array creation with date range and time intervals

I am trying to create an option for user to get possible visit times between two user-chosen dates, 8:00-17:00 every day.
For example: Between 1 Sep to 4 Sep, return [1.09.20 8:00, 1.09.20 8:15 ..., 4.09.20 16:45].
My initial thought was to create two loops, with one iterating through days, second times, but soon I realized Date is not really cooperating with me. Later on I stumbled upon this piece of code to generate just days, without iterating through times, but it was not working for me:
let dates: Date[];
const theDate = new Date(from);
while (theDate < to) {
dates = [...dates, new Date(theDate)];
theDate.setDate(theDate.getDate() + 1);
}
return dates;
Console: (both dates from and to are working, in the log they are shown to be defined)
Sun Aug 23 2020 00:00:00 GMT+0200 (Central European Summer Time)
Sat Aug 29 2020 00:00:00 GMT+0200 (Central European Summer Time)
core.js:4197 ERROR TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))
at VisitService.getDatesBetween (visit.service.ts:31)
at PatientVisitComponent.findVisits (patient-visit.component.ts:88)
at PatientVisitComponent_Template_input_click_28_listener (patient-visit.component.html:49)
at executeListenerWithErrorHandling (core.js:14315)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:14350)
at HTMLInputElement.<anonymous> (platform-browser.js:582)
at ZoneDelegate.invokeTask (zone-evergreen.js:399)
I am open to any pre-build tools, I just need to later on filter this array, to exclude times (saved as Date, but I could change that) that are already taken, and let user to select one to book a visit.
EDIT: Whoops, forgot to add =[]; to the date, so it works, but only for the days. Is there any more elegant solution to do with times?
I would prefer moment instead of Date object but just so we are here, here is how I would do it with Date Object. So first this, the Date object accepts input in the format( Year, Month, Days). You have to follow this in order for you date to output correctly.
let fromMonth = "12";
let fromDay = "02";
let fromYear = "2020";
let toMonth = "12";
let toDay = "05";
let toYear = "2020";
let from = new Date(fromYear+"-"+fromMonth+"-"+fromDay);
let to = new Date(toYear+"-"+toMonth+"-"+toDay);
let dates = [];
while (from < to) {
dates = [...dates, new Date(from)];
from.setDate(from.getDate() + 1);
}
console.log(dates);
In the example above, I have separated days, months, and years for ease of input. As you can as you gradually change the day of either one of them the output will change at per your requirement.
Moment Version:
let fromDate = "05-12-2020";
let toDate = "11-12-2020";
//No need to input date in specific format with moment
let from = moment(fromDate).format('DD-MM-YYYY');
let to = moment(toDate).format('DD-MM-YYYY');
let dates = [];
while (moment(from).isBefore(to)) {
dates = [...dates, new Date(from)];
from = moment(from).add(1,'days'). format('DD-MM-YYYY'); //====> equivalent to from.setDate(from.getDate() + 1);
}
console.log(dates);

get wrong date format javascript

I get wrong output for months that have 29,30,31th. Please help thanks.
//EFFDATE = 29/03/2017;
EFFDATE = document.mainform2.EFFDATE.value;
var dayOfDate = parseFloat(EFFDATE.substring(0,2));
var monthOfDate = parseFloat(EFFDATE.substring(3,5));
var yearOfDate = parseFloat(EFFDATE.substring(6,10));
var date1 = new Date;
var date2 = new Date;
date1.setDate(dayOfDate);
date1.setMonth(monthOfDate -1);
date1.setFullYear(yearOfDate);
console.log(date1);
For example i pick the 29th of March, the system output for date1 is friday march 01 2017.
i pick 30th of March it show friday march 02 2017
It is important to maintain a certain order when you are manipulating dates. Calling new Date will return a date object with the month February. But when you set the day to 29 using setDate, JavaScript will change the date to March, 01 as there is no February, 29 in 2017.
So you either have to set the month first, then the day. Or just use this code:
var EFFDATE = 29/03/2017;
new Date(EFFDATE.split('/').reverse().join('-'));
The setMonth method has an optional second parameter for the day of the month. If it's absent, getDate() is used, and the date is still incomplete.
So this should solve the issue:
date1.setMonth(monthOfDate-1, dayOfDate);
date1.setFullYear(yearOfDate);
Wrong but I'll leave it here for posterity
The second parameter to substring should be the number of characters you want not the index.
If you debugged this and looked at the value of EFFDATE.substring(3,5) you'd see 03/20 not 03 as you were probably thinking.
var dayOfDate = parseFloat(EFFDATE.substring(0,2));
var monthOfDate = parseFloat(EFFDATE.substring(3,5));
var yearOfDate = parseFloat(EFFDATE.substring(6,10));
should be:
var dayOfDate = parseFloat(EFFDATE.substring(0,2));
var monthOfDate = parseFloat(EFFDATE.substring(3,2));
var yearOfDate = parseFloat(EFFDATE.substring(6,4));
UPDATE
I was thinking of substr rather than `substring which is subtley different.

d3.max return wrong date

I have a kind a weird problem. I'm loading data for a overview page. I need to show max date, so users know which time period they're dealing with. Now, I know which date this should be (today or yesterdays date, this is updated once a night) but I would like to do a max function anyway, in case something goes wrong during the update.
The problem I'm having is that both d3.max and a custom max-date function returns the wrong date. One month in the future, so today should show 7/9 2015 but instead it displays 7/10 2015. When I filter the data on 7/10 i get an empty array. In fiddle this works alright so there is something fishy going on. I do run an d3.tsv(tsv is right, even if the extension says .csv the file is in fact tab-separated), might be something there that's causing trouble? Any ideas where i might go wrong? The parsefunction alone returns the right results, the dates when read have the following format: dd.mm.yyyy
//Dateformatting
function parseDate (dateStr) {
var s1 = dateStr.split(" ");
var s1dat = s1[0].split(".");
return new Date(s1dat[2], s1dat[1], s1dat[0])
};
var dateArr = [];
//Occupation
d3.tsv("data.csv", function(error, data, tsv) {
datasetIn = data;
datasetIn.forEach(function(d) {
d.datum = parseDate(d.datum);
d.Patients = +d.Patients.replace(",", ".");
d.Beds= +d.Antal_vardplats.replace(",", ".");
});
for (index = 0; index < datasetIn.length; ++index) {
dateArr.push(datasetIn[index].datum);
}
var maxYear = d3.max(dateArr).getFullYear();
var maxDate = d3.max(dateArr);
})
In JavaScript month values are zero-based beginning with 0 for January to 11 for December. Passing in a human-readable 9 representing September to new Date() is supposed to create a Date object for October instead.
new Date("2015", "9", "7").toDateString(); // "Wed Oct 07 2015"
Adjusting for this should give you the correct result when parsing human-readable date values.

Simple javascript date math... not really

I am trying to create a simple script that gives me the next recycling date based on a biweekly schedule starting on Wed Jul 6, 2011. So I've created this simple function...
function getNextDate(startDate) {
if (today <= startDate) {
return startDate;
}
// calculate the day since the start date.
var totalDays = Math.ceil((today.getTime()-startDate.getTime())/(one_day));
// check to see if this day falls on a recycle day
var bumpDays = totalDays%14; // mod 14 -- pickup up every 14 days...
// pickup is today
if (bumpDays == 0) {
return today;
}
// return the closest day which is in 14 days, less the # of days since the last
// pick up..
var ms = today.getTime() + ((14- bumpDays) * one_day);
return new Date(ms);
}
and can call it like...
var today=new Date();
var one_day=1000*60*60*24; // one day in milliseconds
var nextDate = getNextDate(new Date(2011,06,06));
so far so good... but when I project "today" to 10/27/2011, I get Tuesday 11/8/2011 as the next date instead of Wednesday 11/9/2011... In fact every day from now thru 10/26/2011 projects the correct pick-up... and every date from 10/27/2011 thru 2/28/2012 projects the Tuesday and not the Wednesday. And then every date from 2/29/2012 (leap year) thru 10/24/2012 (hmmm October again) projects the Wednesday correctly. What am I missing? Any help would be greatly appreciated..
V
The easiest way to do this is update the Date object using setDate. As the comments for this answer indicate this isn't officially part of the spec, but it is supported on all major browsers.
You should NEVER update a different Date object than the one you did the original getDate call on.
Sample implementation:
var incrementDate = function (date, amount) {
var tmpDate = new Date(date);
tmpDate.setDate(tmpDate.getDate() + amount)
return tmpDate;
};
If you're trying to increment a date, please use this function. It will accept both positive and negative values. It also guarantees that the used date objects isn't changed. This should prevent any error which can occur if you don't expect the update to change the value of the object.
Incorrect usage:
var startDate = new Date('2013-11-01T11:00:00');
var a = new Date();
a.setDate(startDate.getDate() + 14)
This will update the "date" value for startDate with 14 days based on the value of a. Because the value of a is not the same is the previously defined startDate it's possible to get a wrong value.
Expanding on Exellian's answer, if you want to calculate any period in the future (in my case, for the next pay date), you can do a simple loop:
var today = new Date();
var basePayDate = new Date(2012, 9, 23, 0, 0, 0, 0);
while (basePayDate < today) {
basePayDate.setDate(basePayDate.getDate()+14);
}
var nextPayDate = new Date(basePayDate.getTime());
basePayDate.setDate(nextPayDate.getDate()-14);
document.writeln("<p>Previous pay Date: " + basePayDate.toString());
document.writeln("<p>Current Date: " + today.toString());
document.writeln("<p>Next pay Date: " + nextPayDate.toString());
This won't hit odd problems, assuming the core date services work as expected. I have to admit, I didn't test it out to many years into the future...
Note: I had a similar issue; I wanted to create an array of dates on a weekly basis, ie., start date 10/23/2011 and go for 12 weeks. My code was more or less this:
var myDate = new Date(Date.parse(document.eventForm.startDate.value));
var toDate = new Date(myDate);
var week = 60 * 60 * 24 * 7 * 1000;
var milliseconds = toDate.getTime();
dateArray[0] = myDate.format('m/d/Y');
for (var count = 1; count < numberOccurrences; count++) {
milliseconds += week;
toDate.setTime(milliseconds);
dateArray[count] = toDate.format('m/d/Y');
}
Because I didn't specify the time and I live in the US, my default time was midnight, so when I crossed the daylight savings time border, I moved into the previous day. Yuck. I resolved it by setting my time of day to noon before I did my week calculation.

Javascript getDay returning incorrect values for April, June, September, November

I'm using this script located here: http://www.javascriptkit.com/script/script2/dyndateselector.shtml
If you try it, and go to any of April, June, September or November, you will notice that the day of the week columns are incorrect. Here's a list of incorrect data (the x starts y stuff is showing the following month.)
Bugged months:
4/April (starts Sunday instead of Friday)
May starts Sunday
6/June (starts Friday instead of Wednesday)
July starts Friday
9/September (starts Saturday instead of Thursday)
October starts Saturday
11/November (starts Thursday instead of Tuesday)
December starts Thursday
You'll notice that every bugged month is starting with the day of the following month, yet all the other months seem to be correct.
I can't find anything on this problem. Anyone able to help? The actual Javascript alone can be found here, and the getDay() method occurs on line 125: http://pastebin.com/0zuBYrzv
I've tested in both Firefox and Chrome.
Here's some very simple code to demonstrate the issue:
<script>
var d = new Date();
d.setMonth(5);
d.setFullYear(2011);
d.setDate(1);
alert(d.getDay());
</script>
This will create an alert with the message "5", meaning Friday (5+1 = 6, Friday is the 6th day of the week,) when in fact Wednesday is the start of the week.
This is actually pretty interesting as i am guessing that tomorrow your original code will work as you want again.
What i think is happening is you are creating a new Date and that will automaticly initialize to today (31th of may).
Then you set the Month to June by which you basically say make it 31th of June. This date doesn't exist so javascript will turn it into 1th of July.
Finally you set the Date but since your month is not anymore what you want it to be the results will be wrong.
Looks like 0 is january and 11 is december.
Apparently JavaScript doesn't like it if I set the month, full year, then day. What I must do is set them all in one function, like so:
<script>
var d = new Date();
d.setFullYear(2011, 5, 1);
alert(d.getDay());
</script>
I think this is a bug in Javascript's Date Object.
Please take a look at the following code.
(I'm using w3school's JSref tool online to see it quickly.)
Please note, the ways used below are told by w3 schools themselves.
Some examples of instantiating a date:
var today = new Date()
var d1 = new Date("October 13, 1975 11:13:00")
var d2 = new Date(79,5,24) (//THIS IS WRONG - unexpected results!!!)
var d3 = new Date(79,5,24,11,33,0)
So please be careful when using this Date object, looks like certain ways of instantiating dates are better than others.
<script type="text/javascript">
function whatDayIsToday(date)
{
var weekday=new Array(7);
weekday[0]="Sunday";
weekday[1]="Monday";
weekday[2]="Tuesday";
weekday[3]="Wednesday";
weekday[4]="Thursday";
weekday[5]="Friday";
weekday[6]="Saturday";
document.write("Today is " + weekday[date.getDay()] + ", <br />");
document.write("the " + date.getDay() + getSuffix(date.getDay()) + " day of the week. <br /><br />")
}
function getSuffix(num)
{
return (num>3)?"th":(num==3)?"rd":(num==2)?"nd":(num==1)?"st":"";
}
//CORRECT
var d3 = new Date("01/01/2011");
whatDayIsToday(d3);
//CORRECT
var d2 = new Date("01/01/2011");
whatDayIsToday(d2);
//DOESN'T WORK
var d5 = new Date("1-1-2011");
whatDayIsToday(d5);
//WRONG
var d4 = new Date("2011", "01", "01");
whatDayIsToday(d4);
//DAY OF WEEK IS WRONG
var d = new Date(2011, 1, 1);
whatDayIsToday(d);
//DAY OF WEEK IS ALSO WRONG
var d0 = new Date(11, 1, 1);
whatDayIsToday(d0);
</script>
outputs (all using some format of 1/1/2011) are:
Today is Saturday,
the 6th day of the week. (CORRECT, January first this year was a saturday)
Today is Saturday,
the 6nd day of the week. (CORRECT)
Today is undefined,
the NaNnd day of the week. (WRONG FORMATTING, DOESN'T WORK - EXPECTED)
Today is Tuesday,
the 2nd day of the week. (WRONG - UNEXPECTED)
Today is Tuesday,
the 2nd day of the week. (WRONG - UNEXPECTED)
Today is Wednesday,
the 3nd day of the week. (WRONG - UNEXPECTED)
Based on the other answers to this question, I'm guessing it has to do with the day I'm on currently (8/26/2011) - this would be my starting new Date() and the days and/or years getting applied in the wrong order.
However, it sure would be nice if this thing worked!
This is the typical wrong approach:
var days = ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"];
var d = new Date();
d.setFullYear(selectYear.options[selectYear.selectedIndex].value);
d.setMonth(selectMonth.options[selectMonth.selectedIndex].value-1);
d.setDate(selectDay.options[selectDay.selectedIndex].value);
alert(days[d.getDay()]);
It will work most of the time. But it will have problems with when current date is 31 and when trying to set date to 31 for when set at a month with less than 31 days.
This is a good way:
var days = ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"];
var d = new Date(0); // solves all problems for existing dates
d.setFullYear(selectYear.options[selectYear.selectedIndex].value);
d.setMonth(selectMonth.options[selectMonth.selectedIndex].value-1);
d.setDate(selectDay.options[selectDay.selectedIndex].value);
if( d.getDate() == selectDay.options[selectDay.selectedIndex].value ) {
alert(days[d.getDay()]);
}
else {
alert("this date doesn't exist"); // date was changed cuz date didn't exist
}
Constructing the date with new Date(0) sets the date to 1 jan, this is good because the date is not 31st and january has 31 days which give us the space we need. It wont fail on the 31st and we don't need to set the datas in any special order. It will always works.
If the user sets month to september (30 days) and date to 31 the data object will hold either 1 oct or 1 sep (depending on which order you set them in). Which is irrelevant because they are both wrong. A simple check if the date is what we set it to will tell us if the date is a existing date, if not we can tell the user this.

Categories