Good evening stack. I have this, half made, half copied function which in theory should take a desired date, and append it in a div with 7 next days ahead:
//GLOBAL VARIABLES
var startDate = new Date();
var nextDate = new Date();
var prevDate = new Date();
function GetDates(tDate) {
var aryDates = [];
$("#calendar").empty();
for(var i = 0; i <= 7; i++) {
var currentDate = new Date();
currentDate.setDate(tDate.getDate() + i);
$("#calendar").append("<div class='calendar-day'><p class='weekday'>"+DayAsString(currentDate.getDay())+"</p><p class='day'>"+currentDate.getDate()+"</p><p class='month'>"+MonthAsString(currentDate.getMonth())+"</p><p class='daytime'>Rano</p><p class='daytime'>Popołudnie</p><p class='daytime'>Wieczór</p></div>");
}
nextDate.setDate(tDate.getDate() + 7); //THIS CAUSES THE PROBLEM
prevDate.setDate(tDate.getDate() - 7); //THIS CAUSES THE PROBLEM
console.log("Next Date: " + nextDate);
console.log("Previous Date: " + prevDate);
}
And is fired from jquery document ready:
$(document).ready(function(){
GetDates(startDate); wartosciami od dnia dzisiejszego
var navright = $(".calendar-nav-right");
var navleft = $(".calendar-nav-left");
navright.on("click", function(){GetDates(nextDate);});
navleft.on("click", function(){GetDates(prevDate);});
//console.log(aryDates);
});
The problem lies specifically in the two setDate lines with a comment. It works completely fine untill the result might go beyond a specific calendar month (ie. for april, it will go nuts if the result is > 30).
In the current setting, if I'd click the navleft button causing the calendar to go forward a few times, and print the value of "nextDate" it show me the correct date, yet the dates itself would go in this order:
17april, 18april, 19april, 20april, 21april, 22april, 23april
24april, 25april, 26april, 27april, 28april, 29april, 30april
1april, 2april, 3april, 4april, 5april, 6april, 7april
The only moments when it would shift to another month would be when it fires of on the way, like this:
28april, 29april, 30april, 1may, 2may, 3may, 4may
And when I'd start mixing the next and previous calendar, it gets even more messed up with the starting dates.
I've been seeting at this for 3 hours now and can't find a way to make it work properly.
The error can be found HERE under the tab "2) Wybierz Date"
Any help on the topic would be gratefuly appreciated
Related
The dates go to one month either side and then get stuck in loops. Starting in June, it will go fine to end of July, or start of May, but then loop back to the end/start of those months instead of going further.
globalDate is a React state defined const [globalDate, setGlobalDate] = useState(new Date());
Code Snippet:
//decreasing
const newDate = new Date();
newDate.setDate(globalDate.getDate() - 1);
if (globalDate.getMonth() !== newDate.getMonth()) {
newDate.setMonth(globalDate.getMonth());
}
if (globalDate.getDate() <= 1) {
newDate.setMonth(globalDate.getMonth() - 1);
newDate.setDate(daysInMonth[newDate.getMonth()]);
}
setGlobalDate(newDate);
//increasing
const newDate = new Date();
newDate.setDate(globalDate.getDate() + 1);
if (globalDate.getMonth() !== newDate.getMonth()) {
newDate.setMonth(globalDate.getMonth());
}
if (globalDate.getDate() >= daysInMonth[globalDate.getMonth()]) {
newDate.setMonth(globalDate.getMonth() + 1);
newDate.setDate(1);
}
setGlobalDate(newDate);
Full page source : https://github.com/Westsi/thynkr/blob/master/frontend/web/js/src/Planner.js
The problem in the first code block ("decreasing") occurs when newDate.setMonth() is executed when newDate has a date that is the last day of the month, and the previous month has fewer days. So for instance, it happens when newDate is 31 May at the moment this call to setMonth is made. That call will adjust the date to 31 April, but that date automatically translates to 1 May as April only has 30 days, and so you get stuck in the month of May.
To avoid this kind of problems, just start with globalDate immediately and subtract or add one day. That's all. The overflowing into a next/previous month is something that JavaScript already deals with automatically. So instead of trying to do this yourself (and run into trouble), let JavaScript do this for you:
Decreasing logic:
const newDate = new Date(globalDate); // starting point!
newDate.setDate(globalDate.getDate() - 1); // month overflow happens automatically!
setGlobalDate(newDate); // That's it!
Increasing logic:
const newDate = new Date(globalDate); // starting point!
newDate.setDate(globalDate.getDate() + 1); // month overflow happens automatically!
setGlobalDate(newDate); // That's it!
I am using a function in Angular JS to generate the dates for the past one week starting from today's date. I am storing these dates in an array and then using that array to flood a dropdown.
The following is the code that is being used by me.
generate() {
this.date_new = [];
var date = new Date();
var date1 = new Date();
for (var i = 0; i < 7; i++) {
date.setDate(date1.getDate() - i);
var a = date.toString();
var str = this.convert(a);
this.date_new.push(str);
}
}
Here convert is a function which is being used to convert the dates to the required format. A screenshot of generated dates is attached below.
As evident from the screenshot, the last two dates are incorrect. Can somebody explain to me, what the problem is?
The setDate() method sets the day of the Date object relative to the
beginning of the currently set month.
The above is from MDN.
Your code works for the first 5 dates, but once you are modifying your February date with -1, it sets the day relative to the current month e.g. February. So this will turn into January (as you are setting the day to -1), same happens in the next iteration and you get December.
For an easy fix you can just set the date variable to new Date() in the first line of your for loop.
The issue here is using the same date variable in the loop. You need to re-initialize it.
As can be seen in Parameters Value section in the link here. Zero and negative values in setDate() sets the date from previous month.
Hence at setDate(0), date value is set to last day of Feb. Now since you are using the same variable, setDate(-1) takes the previous month from Feb hence you get Jan.
You need to change the code to something like this:
generate() {
this.date_new = [];
var date1 = new Date();
for (var i = 0; i < 7; i++) {
// re-initialize date
var date = new Date();
date.setDate(date1.getDate() - i);
var a = date.toString();
var str = this.convert(a);
this.date_new.push(str);
}
}
Hope this helps :)
The issue here is that negative numbers inside the setDate method don't work quite well.
Please update the code to something like below:
this.date_new = [];
var date = new Date();
var date1 = new Date();
for (var i = 0; i < 7; i++) {
date= new Date(date1.getFullYear(), date1.getMonth(),date1.getDate()-i);
var a = date.toString();
var str = this.convert(a);
this.date_new.push(str);
}
Hope this will solve your problem.
I'm a bit of a newbie so please bear with me. I've created a date object in javascript every time someone opens a new page. I want to save the time the user opened the page and create another date object exactly one day later to create a countdown timer showing time elapsed from date 1 to date 2.
To accomplish this, I tried subtracting the two dates using .getTime; I want to keep the second date static instead of one day ahead of the current time. Unfortunately, this is not happening even though I have confined d2 (Date 2) to a condition that only runs once and is stored in variable nextday. Here's my JS
$(function (){
localStorage.clear()
var ran = JSON.parse(localStorage.getItem('run'))
d1 = new Date()
var i = 0
if(!ran){
i+=1
d2 = new Date(d1)
nextday = d2.setHours(d1.getHours()+24)
console.log(i)
console.log(typeof(nextday))
localStorage.setItem('run',JSON.stringify('ran'))
localStorage.setItem('nextday',JSON.stringify(nextday))
}
console.log(localStorage)
nday = JSON.parse(localStorage.getItem('nextday'))
console.log(nday)
var seconds = (nday - d1.getTime())
console.log(seconds)
console.log(localStorage)
})
Your script is clearing local storage every time the page is loaded:
localStorage.clear()
This will prevent anything from being stored across runs. Remove it.
You're clearing your localStorage before you access your locally-stored data. Thus, your ran variable is always empty. Remove that one call to clear(), and everything should work fine.
$(function() {
// localStorage.clear() <= the offending code!
var ran = JSON.parse(localStorage.getItem('run'))
d1 = new Date()
var i = 0
if (!ran) {
i += 1
d2 = new Date(d1)
nextday = d2.setHours(d1.getHours() + 24)
console.log(i)
console.log(typeof(nextday))
localStorage.setItem('run', JSON.stringify('ran'))
localStorage.setItem('nextday', JSON.stringify(nextday))
}
console.log(localStorage)
nday = JSON.parse(localStorage.getItem('nextday'))
console.log(nday)
var seconds = (nday - d1.getTime())
console.log(seconds)
console.log(localStorage)
})
http://jsbin.com/ocuceb/6/edit
The above link is where the full code is, I am trying to get a count down timer of how many hours and minutes are left till a business closes.
function countDown() {
var d = new Date();
var hour = d.getHours();
if(hour<10){hour="0"+hour;}
else if(hour>12){hour=hour - 12;}
var minutes = d.getMinutes();
if(minutes<10){minutes="0"+minutes;}
var seconds = d.getSeconds();
if(seconds<10){seconds="0"+seconds;}
var open = weekday[day.getDay()].open.replace(/am/g,'');
var close = weekday[day.getDay()].close.replace(/pm/g,'');
open = parseInt(open,10);
close = parseInt(close,10);
//confused here!
var timeClose = close;
var timeRemaining = Math.floor(d.getHours() - timeClose);
document.write('<br><br>Close At: '+timeClose+"pm<br>Time Remaining:"+timeRemaining);
}
And that is where I am having the trouble, I can get the time of being opened and the time of being closed. Originally I tried this
var timeClose = parseInt(close+':00:00',10);
var difference = Math.floor(d.getDay() - timeClose);
And of course this didn't work, it either said Undefined or NaN I'm not sure how to go about this, the timing is all new to me never needed this though a client asked for this. Where it states the Actual Time, What time they close, and show an image if the time is within the open to close time (basically an Open Neon Sign) and when past closed (a closed Neon Sign)... I figured it would be very simple, though I am having so tricky corners to pass.
JavaScript time does not think in 12-hour format. It thinks in 24-hour format. Change your array of objects to reflect (22 being 10pm):
hours[0]= {open:"8:00:00",close:"22:00:00"};
hours[1]={open:"8:00:00",close:"22:00:00"};
hours[2]={open:"8:00:00",close:"22:00:00"};
hours[3]={open:"8:00:00",close:"22:00:00"};
hours[4]={open:"8:00:00",close:"22:00:00"};
hours[5]={open:"8:00:00",close:"22:00:00"};
hours[6]={open:"8:00:00",close:"22:00:00"};
Also, parsing an int like this could lead to issues:
var timeClose = parseInt(close+':00:00',10);
You should substring everything between the colons to get your desired hours or minutes.
var timeClose = parseInt(open.substring(0,open.indexOf(":")),10);
Also with the way you have it set up, during business hours (or before 10pm), you will always have a negative number because you subtract the current hours from the close time. If it's 8pm and the close time is 10pm, we will have -2 hours remaining? Switch the operands to subtract getHours from time instead:
var timeRemaining = Math.floor(timeClose - d.getHours());
After that, you can probably check timeRemaining for a negative value. If it is negative, that means the business is closed, and you can modify your output message to reflect as such, i.e.
var timeRemaining = Math.floor(timeClose - d.getHours());
if (timeRemaining < 0) {
output = "Sorry we are closed already";
} else {
output = "You have " + timeRemaining + " to come in and shop till you drop";
}
I think a simpler way to do this would be something like this
var now=new Date();
var closing=new Date(now.getFullYear(),now.getMonth(),now.getDate(),21);//Set this to 10:00pm on the present day
var diff=closing-now;//Time difference in milliseconds
if(now.getHours<7){
//It's before opening time
}
else if(diff<0){
//It's after closing time
}
else{
var hours=Math.floor(diff/(1000*60*60));
diff=diff%(1000*60*60);
var mins=Math.floor(diff/(1000*60));
diff=diff%(1000*60);
var secs=Math.floor(diff/(1000));
}
Here is a reference on the time object https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
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.