I always have problems figuring out dates functions
var d = new Date(),
month = d.getMonth(),
mondays = [];
d.setDate(1);
// Get the first Monday in the month
while (d.getDay() !== 1) {
d.setDate(d.getDate() + 1);
}
// Get all the other Mondays in the month
while (d.getMonth() === month) {
var pushDate = new Date(d.getTime());
mondays.push(pushDate.getDate() + '-' + (pushDate.getMonth()+1) + '-' + pushDate.getFullYear());
d.setDate(d.getDate() + 7);
}
I am using this function to get all mondays in a month, current month.
How can I adapt this code to get all remaining mondays in the year?
Just loop through the year instead of the month. The code is the same as yours, it works fine. just changed month -> year and getMonth() -> getYear()
var d = new Date(),
year = d.getYear(),
mondays = [];
d.setDate(1);
// Get the first Monday in the month
while (d.getDay() !== 1) {
d.setDate(d.getDate() + 1);
}
// Get all the other Mondays in the month
while (d.getYear() === year) {
var pushDate = new Date(d.getTime());
mondays.push(pushDate.getDate() + '-' + (pushDate.getMonth()+1) + '-' + pushDate.getFullYear());
d.setDate(d.getDate() + 7);
}
var x = new Date();
//set the financial year starting date
x.setFullYear(2016, 03, 01);
//set the next financial year starting date
var y = new Date();
y.setFullYear(2017, 03, 01);
var j = 1;
var count = 0;
//getting the all mondays in a financial year
for (var i = 0; x < y; i += j) {
if (x.getDay() === 1) {
document.write("Date : " + x.getDate() + "/" +
(x.getMonth() + 1) + "<br>");
x = new Date(x.getTime() + (7 * 24 * 60 * 60 * 1000));
j = 7;
count++;
} else {
j = 1;
x = new Date(x.getTime() + (24 * 60 * 60 * 1000));
}
}
document.write("total mondays : " + count + "<br>");
This is just an alternative, it uses a simpler method of getting the first day of the month.
// Get all Mondays in year from provided date
// Default today's date
function getMondays(d) {
// Copy d if provided
d = d ? new Date(+d) : new Date();
// Set to start of month
d.setDate(1);
// Store end year and month
var endYear = d.getFullYear() + 1;
var endMonth = d.getMonth();
// Set to first Monday
d.setDate(d.getDate() + (8 - (d.getDay() || 7)) % 7);
var mondays = [new Date(+d)];
// Create Dates for all Mondays up to end year and month
while (d.getFullYear() < endYear || d.getMonth() != endMonth) {
mondays.push(new Date(d.setDate(d.getDate() + 7)));
}
return mondays;
}
// Get all Mondays and display result
// SO console doensn't show all results
var mondays = getMondays();
mondays.forEach(function(mon) {
console.log(mon.toLocaleString(void 0, {
weekday: 'short',
day: 'numeric',
month: 'short',
year: 'numeric'
}));
});
// Count of Mondays, not all shown in SO console
console.log('There are ' + mondays.length + ' Mondays, the first is ' + mondays[0].toString())
With date-fns
https://date-fns.org/v2.28.0/docs/eachWeekOfInterval
eachWeekOfInterval({
start: new Date('2022/01/01'),
end: new Date('2022/5/31')
}, { weekStartsOn: 1 })
Related
How can I get all week number, from/to date of specific month?
The below code is what I construct to display week number, from/to date of specific month
and it returns infinite loop whenever I insert the function inside loop.
function getISOWeeksInMonth(month, year) {
let weekStart = new Date(year, month - 1, 1);
weekStart.setDate(weekStart.getDate() - (weekStart.getDay() || 7) + 1);
let weekEnd = new Date(weekStart);
weekEnd.setDate(weekEnd.getDate() + 6);
let weekNum = moment(weekStart, "YYYY-MM-DD").week()
let weeks = [];
do {
weeks.push({
weekNum : weekNum++,
start: new Date(weekStart),
end: new Date(weekEnd)
});
weekStart.setDate(weekStart.getDate() + 7);
weekEnd.setDate(weekEnd.getDate() + 7);
} while (weekStart.getMonth() < month);
return weeks;
}
_.forEach(moment.months(), function (month_name) {
var month_number = moment().month(month_name).format("MM");
getISOWeeksInMonth(month_number, 2022).forEach(week => console.log(
'Week : ' + week.weekNum +
'\nStart: ' + week.start.toDateString() +
'\nEnd : ' + week.end.toDateString())
);
})
Result should return the list the week number, from/to date
Sample Url:
https://savvytime.com/week-number/philippines/2022
Here is the sample when I run the function outside loop:
function getISOWeeksInMonth(month, year) {
let weekStart = new Date(year, month - 1, 1);
weekStart.setDate(weekStart.getDate() - (weekStart.getDay() || 7) + 1);
let weekEnd = new Date(weekStart);
weekEnd.setDate(weekEnd.getDate() + 6);
let weekNum = moment(weekStart, "YYYY-MM-DD").week()
let weeks = [];
do {
weeks.push({
weekNum : weekNum++,
start: new Date(weekStart),
end: new Date(weekEnd)
});
weekStart.setDate(weekStart.getDate() + 7);
weekEnd.setDate(weekEnd.getDate() + 7);
} while (weekStart.getMonth() < month);
return weeks;
}
getISOWeeksInMonth(1, 2022).forEach(week => console.log(
'Week : ' + week.weekNum +
'\nStart: ' + week.start.toDateString() +
'\nEnd : ' + week.end.toDateString())
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>
function getISOWeeksInMonth(month, year) {
let weekStart = new Date(year, month - 1, 1);
weekStart.setDate(weekStart.getDate() - (weekStart.getDay() || 7) + 1);
let weekEnd = new Date(weekStart);
weekEnd.setDate(weekEnd.getDate() + 6);
let weeks = [];
do {
let weekNum = moment(weekStart, "YYYY-MM-DD").week()
weeks.push({
weekNum : weekNum,
start: new Date(weekStart),
end: new Date(weekEnd)
});
weekStart.setDate(weekStart.getDate() + 7);
weekEnd.setDate(weekEnd.getDate() + 7);
} while (weekStart.getMonth() < month && (weekStart.getMonth() || (month < 12) ));
return weeks;
}
let _ = moment.months()
_.forEach(function (month_name) {
var month_number = moment().month(month_name).format("MM");
getISOWeeksInMonth(month_number, 2022).forEach(week => console.log(
'Week : ' + week.weekNum +
'\nStart: ' + week.start.toDateString() +
'\nEnd : ' + week.end.toDateString())
);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.2/moment.min.js"></script>
When you calculate the weeks in December (month 12), you're starting with the last week in the prior month (November, i.e. 11), and in your do {...} while loop, you're adding 7 days to weekStart. So far so good, but your while (weekStart.getMonth() < month) is checking the 0-11 value of weekStart.getMonth(), and when it rolls forward from 11, instead of going to 12 it goes to 0. So it is always less than 12 (December!)!
You can fix this by adjusting your while to:
while (weekStart.getMonth() < month && (weekStart.getMonth() || (month < 12) ))
This question already has answers here:
Incrementing a date in JavaScript
(19 answers)
Closed 1 year ago.
I'm trying to add 3 days to a random date but instead it seems as though I'm adding a month.
var d = new Date(2021, 9, 14);
var currentTime = d.getTime();
var daysToAdd = 3;
var secondsInADay = 86400;
var d = new Date(currentTime + daysToAdd * secondsInADay);
var year = d.getFullYear();
var month = ("0" + (d.getMonth() + 1)).slice(-2);
var day = ("0" + d.getDate()).slice(-2);
console.log('result is:' + year + '-' + month + '-' + day);
Try this :
var d = new Date(2021, 9, 14) ;
var daysToAdd = 3;
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
console.log(date.addDays(daysToAdd));
You're multiplying by the number of seconds in a day, but you need to multiply by the number of milliseconds in a day, as shown below:
var d = new Date(2021, 9, 14);
var currentTime = d.getTime();
var daysToAdd = 3;
var milisecondsInADay = 86400000;
var d = new Date(currentTime + daysToAdd * milisecondsInADay);
var year = d.getFullYear();
var month = ("0" + (d.getMonth() + 1)).slice(-2);
var day = ("0" + d.getDate()).slice(-2);
console.log('result is:' + year + '-' + month + '-' + day);
In google apps script I use often in summertimeperiod GMT+2 or in wintertime GMT+1 for the correct date.
To avoid to change this twice a year manually i developped following function:
function StartSummerWintertime() {
var i;
var today;
var year;
var SST;
var SWT;
var day;
var GMT_time;
today = new Date();
Logger.log("today = " + today)
year = today.getFullYear();
//Summertime starts last Sunday in March.
for (i = 31; i > 24; i--) {
SST = new Date("March " + i + "," + year);
day = SST.getDay();
if (day == 0) {
break;
}
}
Logger.log("Start date Summertime "+year+" = " + SST)
//Wintertime starts last Sunday in October.
for (i = 31; i > 24; i--) {
SWT = new Date("Oct " + i + "," + year);
day = SWT.getDay();
if (day == 0) {
break;
}
}
Logger.log("Start date Wintertime "+year+" = " + SWT)
//The switch takes place at 2:00 AM, so I have added 2 hours (= 2 * 60 * 60 * 1000 ms)
if (today.getTime() < (SST.getTime() + 2*60*60*1000) || today.getTime() > SWT.getTime() + (2*60*60*1000)) {
GMT_time = "GMT+1";
}
else {
GMT_time = "GMT+2";
}
Logger.log("GMT_time = " + GMT_time)
var date1 = Utilities.formatDate(new Date("July 6, 2021"), "GMT+2", "d-M-yyyy");
var date2 = Utilities.formatDate(new Date("July 6, 2021"), "GMT+1", "d-M-yyyy");
Logger.log("date1 = " + date1)
Logger.log("date2 = " + date2)
var date3 = Utilities.formatDate(new Date("July 6, 2021"), GMT_time, "d-M-yyyy");
var date4 = Utilities.formatDate(new Date("July 6, 2021"), GMT_time, "d-M-yyyy");
Logger.log("date3 = " + date3)
Logger.log("date4 = " + date4)
}
Date 1 and date 2 give different dates, date 3 and date 4 give correct (same) dates. The problem is solved however there should be a smarter (shorter) way to do so.
Please advise.
I got this from another stack question
incr_date(date_str){
let parts = date_str.split("-");
let dt = new Date(
parseInt(parts[0], 10), // year
parseInt(parts[1], 10) - 1, // month (starts with 0)
parseInt(parts[2], 10) // date
);
dt.setDate(dt.getDate() + 1);
parts[0] = "" + dt.getFullYear();
parts[1] = "" + (dt.getMonth() + 1);
if (parts[1].length < 2) {
parts[1] = "0" + parts[1];
}
parts[2] = "" + dt.getDate();
if (parts[2].length < 2) {
parts[2] = "0" + parts[2];
}
return parts.join("-");
}
It works but how can I convert this function to decrement the date instead of increment?
I'm doing this on a react native component so I dont want to import any javascript libraries like moment.js
function dateAdd(dte){
var date = new Date(dte);
date.setDate(date.getDate() + 1);
console.log("add one day= "+date)
}
function datesub(dte){
var date = new Date(dte);
date.setDate(date.getDate() - 1);
console.log("minus one day = "+ date)
}
dateAdd("01-01-2017")
datesub("01-01-2017")
I'd convert the string to Javascript understandable format, increment a day and convert it back to user understandable format. I'm using the flag(Boolean) to determine weather to Increment the date and vice versa.
var convertDate = function(dt, flag) {
var dateArr = dt.split('-');
var tempDate = new Date();
var mm = dateArr[1] - 1; //Javascript considers 0 as Jan
tempDate.setFullYear(dateArr[0]);
tempDate.setMonth(mm);
tempDate.setDate(dateArr[2]);
if (flag) {
tempDate.setDate(tempDate.getDate(dateArr[2]) + 1);//Add's one day
} else {
tempDate.setDate(tempDate.getDate(dateArr[2]) - 1);//Sub's one day
}
var userFriendlyMonth = (Number(tempDate.getMonth()) + 1); //user considers 1 as Jan
return tempDate.getFullYear() + '-' + userFriendlyMonth + '-' + tempDate.getDate();
}
document.getElementById("increment").innerHTML = convertDate('2018-11-30', true);
document.getElementById("decrement").innerHTML = convertDate('2018-11-30', false);
<div>Increment: <span id="increment"></span></div>
<div>Decrement: <span id="decrement"></span></div>
I am looking to calculate the age in years, months and days using JavaScript. This code works for some dates, however it doesn't work if the date is less than 1 year away or anytime in the past at all.
function age(year, month, day) {
var today = new Date();
var endDate = new Date(year, month, day).getTime();
var dayDiff = Math.floor((endDate - today) / 86400000);
if (dayDiff >= 365) {
var year = Math.floor(dayDiff / 365);
var remainder = Math.floor(dayDiff) - (year * 365);
var months = Math.floor(remainder / 30);
}
var days = Math.floor(remainder) - (months * 30);
return year + " years" + " " + months + " months" + " " + days + " days";
}
console.log(age(2017, 11, 17));
console.log(age(2015, 3, 6));
however it doesn't work if the date is less than 1 year away or anytime in the past at all.
Look at the conditional of your code:
if (dayDiff >= 365) {
...
}
That would explain why it's not triggering when the date is less than 1 year (365 days) away.
You have 2 options : either strip the if (dayDiff >= 365) condition altogether or write an else statement to your if to handle cases where dayDiff < 365.
Following your logic:
function age(year, month, day) {
var today = new Date();
var endDate = new Date(year, month, day).getTime();
var dayDiff = Math.floor((endDate - today) / 86400000);
if (dayDiff >= 365) {
var year = Math.floor(dayDiff / 365);
var remainder = Math.floor(dayDiff) - (year * 365);
var months = Math.floor(remainder / 30);
} else {
var year = 0;
var remainder = Math.floor(dayDiff) - (year * 365);
var months = Math.floor(remainder / 30);
}
var days = Math.floor(remainder) - (months * 30);
return year + " years" + " " + months + " months" + " " + days + " days";
}
document.write("<p>" + age(2017, 11, 17) + "</p>");
document.write("<p>" + age(2016, 7, 11) + "</p>");
I would suggest this function to get the "natural" number of years, months and days between two dates:
function interval(date1, date2) {
if (date1 > date2) { // swap
var result = interval(date2, date1);
result.years = -result.years;
result.months = -result.months;
result.days = -result.days;
return result;
}
result = {
years: date2.getYear() - date1.getYear(),
months: date2.getMonth() - date1.getMonth(),
days: date2.getDate() - date1.getDate()
};
if (result.days < 0) {
result.months--;
// days = days left in date1's month,
// plus days that have passed in date2's month
var copy1 = new Date(date1.getTime());
copy1.setDate(32);
result.days = 32-date1.getDate()-copy1.getDate()+date2.getDate();
}
if (result.months < 0) {
result.years--;
result.months+=12;
}
return result;
}
// Be aware that the month argument is zero-based (January = 0)
var date1 = new Date(2015, 4-1, 6);
var date2 = new Date(2015, 5-1, 9);
document.write(JSON.stringify(interval(date1, date2)));
This solution will treat leap years (29 February) and month length differences in a way we would naturally do (I think).
So for example, the interval between 28 February 2015 and 28 March 2015 will be considered exactly one month, not 28 days. If both those days are in 2016, the difference will still be exactly one month, not 29 days.
Dates with exactly the same month and day, but different year, will always have a difference of an exact number of years. So the difference between 2015-03-01 and 2016-03-01 will be exactly 1 year, not 1 year and 1 day (because of counting 365 days as 1 year).