How to increase the date when moving to the other month - javascript

I have a date set which I am filling it with the number of current week and year:
dateSets(week, year) {
let fistDayOfTheWeek = '';
if(this.currentWeekNumber === this.getWeekNumber(new Date())) {
fistDayOfTheWeek = new Date();
} else {
fistDayOfTheWeek = this.getDateOfWeek(week, year);
}
let sunday = new Date(fistDayOfTheWeek);
sunday.setDate(sunday.getDate() - sunday.getDay() + 7);
const dates = [];
const diff = sunday.getDate() - fistDayOfTheWeek.getDate();
for (let i = 0; i <= diff; i++) {
const upDate = new Date();
upDate.setDate(fistDayOfTheWeek.getDate() + i);
dates.push(upDate);
}
console.log(dates)
return dates;
},
So apperantly my dateSet function works like if it is not monday then show the dates from today to sunday and from next week from monday to sunday. But what is wrong in this function is it doesnt push when the month is changed. So for 4 weeks console.log(dates) displays:
[Tue Aug 10 2021 16:22:43 GMT+0200 (Central European Summer Time),
Wed Aug 11 2021 16:22:43 GMT+0200 (Central European Summer Time), Thu
Aug 12 2021 16:22:43 GMT+0200 (Central European Summer Time), Fri Aug
13 2021 16:22:43 GMT+0200 (Central European Summer Time), Sat Aug 14
2021 16:22:43 GMT+0200 (Central European Summer Time), Sun Aug 15
2021 16:22:43 GMT+0200 (Central European Summer Time)]
[Mon Aug 16 2021 16:22:46 GMT+0200 (Central European Summer Time),
Tue Aug 17 2021 16:22:46 GMT+0200 (Central European Summer Time), Wed
Aug 18 2021 16:22:46 GMT+0200 (Central European Summer Time), Thu Aug
19 2021 16:22:46 GMT+0200 (Central European Summer Time), Fri Aug 20
2021 16:22:46 GMT+0200 (Central European Summer Time), Sat Aug 21
2021 16:22:46 GMT+0200 (Central European Summer Time), Sun Aug 22
2021 16:22:46 GMT+0200 (Central European Summer Time)]
[Mon Aug 23 2021 16:22:47 GMT+0200 (Central European Summer Time),
Tue Aug 24 2021 16:22:47 GMT+0200 (Central European Summer Time), Wed
Aug 25 2021 16:22:47 GMT+0200 (Central European Summer Time), Thu Aug
26 2021 16:22:47 GMT+0200 (Central European Summer Time), Fri Aug 27
2021 16:22:47 GMT+0200 (Central European Summer Time), Sat Aug 28
2021 16:22:47 GMT+0200 (Central European Summer Time), Sun Aug 29
2021 16:22:47 GMT+0200 (Central European Summer Time)]
[]
As you see since after 3 weeks, the month will be changed to september and I think that's why it comes to an empty array.
I dont know if it is necessary but in any case here are the other functions that I used:
getDateOfWeek(w, y) {
var simple = new Date(y, 0, 1 + (w - 1) * 7);
var dow = simple.getDay();
var ISOweekStart = simple;
if (dow <= 4)
ISOweekStart.setDate(simple.getDate() - simple.getDay() + 1);
else
ISOweekStart.setDate(simple.getDate() + 8 - simple.getDay());
return ISOweekStart;
}
getWeekNumber(date) {
const temp_date = new Date(date.valueOf());
const dayn = (date.getDay() + 6) % 7;
temp_date.setDate(temp_date.getDate() - dayn + 3);
const firstThursday = temp_date.valueOf();
temp_date.setMonth(0, 1);
if (temp_date.getDay() !== 4)
{
temp_date.setMonth(0, 1 + ((4 - temp_date.getDay()) + 7) % 7);
}
return 1 + Math.ceil((firstThursday - temp_date) / 604800000);
},
PS: currentWeekNumber is increasing everytime when the button is clicked.

Your issue is here:
const diff = sunday.getDate() - fistDayOfTheWeek.getDate();
when you get to the end of the month of say August, the next Sunday is 5 Sep and the first day of the week is 30 August, so diff is -25 and in the test:
for (let i = 0; i <= diff; i++) {
i is less than diff from the start so nothing is added to the array.
One fix is to get the number of days until the next Sunday and iterate for that many days, e.g.
// Return an array of dates from tomorrow until the
// following Sunday.
function getDatesToSunday(date = new Date()) {
// Copy date so don't affect original
let d = new Date(+date);
// Get the number of days until the next Sunday
let count = 7 - d.getDay();
// Create array of Dates
let dates = [];
while (count--) { 
dates.push (new Date(d.setDate(d.getDate() + 1)));
}
return dates;
}
console.log('Given Sun 29 Aug 2021:');
getDatesToSunday(new Date(2021, 7, 29))
.forEach(d => console.log(d.toDateString()));
console.log('Rest of this week, or next if today is Sunday:');
getDatesToSunday()
.forEach(d => console.log(d.toDateString()));
If the supplied date is Saturday, the above returns an array of just Sunday. If the supplied date is Sunday, it returns an array of the following Monday to Sunday, etc.
If you want to get multiple weeks of dates, add a second parameter, say weeks that defaults to 1, then add (weeks - 1) * 7 to count before the while loop. Test weeks first to ensure it's 1 or greater (starting a decrementing while loop with a negative number is not a good idea).
Or you can just keep adding days until Sunday:
const getDatesToSunday = (date = new Date()) => {
// Setup
let year = date.getFullYear(),
month = date.getMonth(),
day = date.getDate(),
dates = [];
// Add dates from tomorrow until Sunday
do {
dates.push(new Date(year, month, ++day));
} while (dates[dates.length - 1].getDay());
return dates;
};
getDatesToSunday().forEach(d=>console.log(d.toDateString()));

Related

Modify "Round to nearest interval" function so that it works with intervals above 1 hour

Consider this function that rounds down to the nearest interval:
function roundToNearest(value, interval) {
return Math.floor(value/interval) * interval;
}
Date.now()
> Thu Sep 01 2022 05:38:11 GMT+0300 (Eastern European Summer Time)
Now run it with 5 minutes:
new Date(roundToNearest(Date.now(), 1000*60*5))
> Thu Sep 01 2022 05:35:00 GMT+0300 (Eastern European Summer Time)
15 minutes:
new Date(roundToNearest(Date.now(), 1000*60*15))
> Thu Sep 01 2022 05:30:00 GMT+0300 (Eastern European Summer Time)
1 hour:
new Date(roundToNearest(Date.now(), 1000*60*60*1))
> Thu Sep 01 2022 05:00:00 GMT+0300 (Eastern European Summer Time)
2 hours:
new Date(roundToNearest(Date.now(), 1000*60*60*2))
>Thu Sep 01 2022 03:00:00 GMT+0300 (Eastern European Summer Time) (should be 04:00:00)
Intervals 1 hour and below return the expected results, but 2 hours (and any interval above 2 hours) does not (04:00:00 was expected for 2 hours, for example). How can I modify it so that it works on intervals above 1 hour?
I think what you need here is to round the time since midnight. That is, if the time is 05:30 with 2 hour rounding you want 04:00, or for 6 hour rounding you want 00:00.
We get the interval since local midnight, round to the desired number, then add to midnight. We'll create a few helper functions getMidnight() and getTimeSinceMidnight().
We'll then combine to create a roundSinceMidnight() function.
function roundSinceMidnight(date, interval) {
return roundToNearest(getTimeSinceMidnight(date), interval) + getMidnight(date);
}
function roundToNearest(value, interval) {
return Math.floor(value/interval) * interval;
}
function getMidnight(date) {
const d = new Date(date); // date could be a Date object or ms since 1970...
return new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
}
function getTimeSinceMidnight(date) {
return date - getMidnight(date);
}
console.log('1 hour: ', new Date(roundSinceMidnight(Date.now(), 1000*60*60*1)).toTimeString())
console.log('2 hours:', new Date(roundSinceMidnight(Date.now(), 1000*60*60*2)).toTimeString())
console.log('4 hours:', new Date(roundSinceMidnight(Date.now(), 1000*60*60*4)).toTimeString())
console.log('6 hours:', new Date(roundSinceMidnight(Date.now(), 1000*60*60*6)).toTimeString())
.as-console-wrapper { max-height: 100% !important; }
You may pass over for the time difference in your timezone. Let's subtract +0300 from 03:00:00. I don't prove it correct, but the following might work for you:
new Date(roundToNearest(Date.now() + 1000*60*60*3, 1000*60*60*2) - 1000*60*60*3)

Why is getDate() a month off?

I'm trying to iterate over objects that have a date within a specific time frame. These time frames are days in the past week bounded by startDate and endDate.
I have a for loop that sets the startDate to the beginning of the day, and endDate will be the end of the day.
let startDate = new Date(); // startDate: Start bound of average execution time calculation
let endDate = new Date(); // endDate: End bound of average execution time calculation
for (let i = 0; i < 7; i++) {
// i is used to decrement the startDate to i days from today
// set startDate to beginning of the day
startDate = new Date();
startDate.setDate(startDate.getDate() - i);
startDate.setHours(0, 0, 0, 0);
console.log(i + ": " + startDate);
// set endDate to end of the day
endDate.setDate(startDate.getDate());
endDate.setHours(23, 59, 59, 999);
console.log(i + ": " + endDate);
However, even though I'm setting the endDate to the startDate, the console tells me that the endDate is one month off. Why is this happening?
The console shows this:
0: Sat Aug 01 2020 00:00:00 GMT-0700 (Mountain Standard Time)
0: Sat Aug 01 2020 23:59:59 GMT-0700 (Mountain Standard Time)
1: Fri Jul 31 2020 00:00:00 GMT-0700 (Mountain Standard Time)
1: Mon Aug 31 2020 23:59:59 GMT-0700 (Mountain Standard Time)
2: Thu Jul 30 2020 00:00:00 GMT-0700 (Mountain Standard Time)
2: Sun Aug 30 2020 23:59:59 GMT-0700 (Mountain Standard Time)
3: Wed Jul 29 2020 00:00:00 GMT-0700 (Mountain Standard Time)
3: Sat Aug 29 2020 23:59:59 GMT-0700 (Mountain Standard Time)
4: Tue Jul 28 2020 00:00:00 GMT-0700 (Mountain Standard Time)
4: Fri Aug 28 2020 23:59:59 GMT-0700 (Mountain Standard Time)
5: Mon Jul 27 2020 00:00:00 GMT-0700 (Mountain Standard Time)
5: Thu Aug 27 2020 23:59:59 GMT-0700 (Mountain Standard Time)
Think like arrays, where the first element is 0. The same is true here. The months of the year will be 0 - 11, rather than 1 - 12. The getMonth() method returns the month in the specified date according to local time, as a zero-based value (where zero indicates the first month of the year).
Also, keep this in mind: With setDate() the expected values are 1-31, but other values are allowed: 0 will result in the last day of the previous month. -1 will result in the day before the last day of the previous month.
So, I ended up just fixing it by not referring to startDate at all. I'm not sure why I can't call getDate() without getting the wrong date, but for now, I'll just set endDate by repeating whatever I did to startDate.
// set startDate to beginning of the day
startDate = new Date();
startDate.setDate(startDate.getDate() - i);
startDate.setHours(0, 0, 0, 0);
console.log(i + ": " + startDate);
// set endDate to end of the day
endDate = new Date();
endDate.setDate(endDate.getDate() - i);
endDate.setHours(23, 59, 59, 59);
console.log(i + ": " + endDate);
The reason it happens is because you are setting the date but not the month, so when the loop crosses a month boundary, the start goes to the previous month but end stays in the current month.
When run on 1 Aug, in the first iteration both start and end are set to 1 Aug.
In the next iteration, 1 is subtracted from the start so it's 31 July, but then just the date is set for end, so it goes to 31 Aug, and so on…
A reworking of the code:
// Start at random time on 1 Aug
let d = new Date(2020,7,1,15,23,51,3);
for (let start, end, i=0; i<7; i++) {
start = new Date(d.setHours(0,0,0,0));
console.log(i + ' : ' + start.toString());
end = new Date(d.setHours(23,59,59,999));
console.log(i + ' : ' + end.toString());
d.setDate(d.getDate() - 1);
}

javascript - date difference should be zero but it is 18 hours

This one has stumped me. It should be so simple I would think. I am doing some very simple date subtraction in Javascript. I am subtracting the same dates and I would think it would give zero hours, but it gives 18 hours.
let inDate = new Date('Tue Aug 27 2019 00:00:00 GMT-0500 (Central Daylight Time)').getTime();
let outDate = new Date('Tue Aug 27 2019 00:00:00 GMT-0500 (Central Daylight Time)').getTime();
document.getElementById('date').innerHTML = new Date(outDate - inDate);
<div id='date'>
</div>
In case it produces different results based on where you are, the result I am getting is this:
Wed Dec 31 1969 18:00:00 GMT-0600 (Central Standard Time)
This is due to your timezone. If you convert to GMT String before print it the time will be correct. (Jan 01, 1969 00:00:00)
new Date(outDate - inDate).toGMTString()
You should see the correct date.
let inDate = new Date('Tue Aug 27 2019 00:00:00 GMT-0500 (Central Daylight Time)').getTime()
let outDate = new Date('Tue Aug 27 2019 00:00:00 GMT-0500 (Central Daylight Time)').getTime()
console.log(new Date(inDate - outDate).toGMTString())

Difference between 2 dates, should work, but it isn't

i have got the following code which should simply tell me difference between 2 months, however all that it is returning is 1 and I can't figure it out!
function parseDate(str) {
function pad(s) { return (s < 10) ? '0' + s : s; }
var d = new Date(str);
return d;
}
Array.prototype.monthDifference = function() {
var months = this[1].getMonth() - this[0].getMonth() + (12 * (this[1].getFullYear() - this[0].getFullYear()));
if(this[1].getDate() < this[0].getDate()){
months--;
}
return months;
};
console.log([parseDate('01/01/2017'), parseDate('02/04/2017')].monthDifference());
Edit
Okay, see updated code below:
Array.prototype.monthDifference = function() {
console.log((this[1].getMonth()+1) - (this[0].getMonth()+1));
var months = (this[1].getMonth()+1) - (this[0].getMonth()+1) + (12 * (this[1].getFullYear() - this[0].getFullYear()));
if(this[1].getDate() < this[0].getDate()){
months--;
}
return (months > 1) ? 0 : months;
};
[pubDate, new Date()].monthDifference();
And now the output, how is one of the numbers negative and the other positive!? And comparing against today and dates in the past...
1
Sat Apr 27 1907 00:00:00 GMT+0100 (BST) Wed May 28 1902 00:00:00 GMT+0100 (BST)
-10
Wed Mar 26 1930 00:00:00 GMT+0000 (GMT) Wed May 28 1902 00:00:00 GMT+0100 (BST)
-10
Tue Mar 26 1929 00:00:00 GMT+0000 (GMT) Wed May 28 1902 00:00:00 GMT+0100 (BST)
-10
Tue Mar 26 1929 00:00:00 GMT+0000 (GMT) Wed May 28 1902 00:00:00 GMT+0100 (BST)
-1
Tue Jun 24 1913 00:00:00 GMT+0100 (BST) Wed May 28 1902 00:00:00 GMT+0100 (BST)
What about this ?
It gives days between two date.
Array.prototype.monthDifference = function() {
var b = this[0].getTime();
var x = this[1].getTime();
var y = x-b;
return Math.floor(y / (24*60*60*1000));
};
var a = [];
a.push(parseDate('01/01/2016'));
a.push(parseDate('02/04/2017'));
console.log(a.monthDifference());
The JavaScript Date constructor doesn't parse strings in UK format(dd/mm/yyyy).
You can split the date string and and then pass it into Date constructor.
Working fiddle: Date foramte fiddle
function formateDateToUK(dateString){
var splitDate = dateString.split('/'),
day = splitDate[0],
month = splitDate[1] - 1, //Javascript months are 0-11
year = splitDate[2],
formatedDate = new Date(year, month, day);
return formatedDate;
}
you functions returns '1', since it is the correct result :)
try:
console.log([parseDate('01/01/2017'), parseDate('07/01/2017')].monthDifference());
and it returns '6'... which is correct.
Note: 'new Date(str)' expects "MM/dd/yyyy" not "dd/MM/yyyy".
Hope this helps

31 days in February in Date object

This code should log all days for given month:
var date = new Date(2012,2,1);
var thisMonth = date.getMonth();
while(date.getMonth()==thisMonth) { // 31 steps ???
console.log(date.getMonth(),date.getDate());
date.setDate(date.getDate()+1);
}
It works well for every month but February. Any ideas where is the catch?
Note the month parameter is 0-indexed, so your code is about March not February.
The doc:
month
Integer value representing the month, beginning with 0 for January to
11 for December.
Use new Date(2012,1,1); month is zero-based ;-)
This is pretty interesting:
new Date('2014-02-28'); // Fri Feb 28 2014 01:00:00 GMT+0100
new Date('2014-02-29'); // Sat Mar 01 2014 01:00:00 GMT+0100
new Date('2014-02-30'); // Sun Mar 02 2014 01:00:00 GMT+0100
new Date('2014-02-31'); // Mon Mar 03 2014 01:00:00 GMT+0100
new Date('2014-02-32'); // Invalid Date

Categories

Resources