how to get all weekdays from a date range and duration - javascript

So i have an initialDate, a travelTime and a endDate,
we also have booleans representing the weekdays
lets say we whave the following:
initialDate = 06 Jun 2021
travelTime = 13:00 to 18:00
mon = true, tue = false, wed = true, thu: false, fri = false
endDate = initialDate + 1 month
i need to get all mondays and wednesday dates between initialDate and endDate

In this code bellow, using momentjs, I create two array, one for Mondays and one for Wednesdays formatted like you wrote the date in your question.
const dateFormatTemplate = 'DD MMM YYYY';
const initialDate = moment('06 Jun 2021', dateFormatTemplate);
const endDate = moment(initialDate).add(1, 'month');
const MONDAY = 1; // moment().day() return a value from 0 to 6(Sunday-to-Saturday)
const WEDNESDAY = 3;
const mondayArray = [];
const wednesdayArray = [];
while (initialDate.isSameOrBefore(endDate)) {
if (initialDate.day() === MONDAY) mondayArray.push(initialDate.format(dateFormatTemplate));
else if (initialDate.day() === WEDNESDAY) wednesdayArray.push(initialDate.format(dateFormatTemplate));
initialDate.add(1, 'day');
}
console.log('ALL MONDAY', mondayArray)
console.log('ALL WEDNESDAY', wednesdayArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>

Related

Google Apps Script: Is a date part with a range

I would like to determine what season a date falls between. The date is in a cell and is not related to the current date.
I have gotten this far:
var myDate=myForm.getRange("C4").getValue();
if (Utilities.formatDate(myDate, "GMT", 'MM/dd')>'12/21' && Utilities.formatDate(myDate, "GMT", 'MM/dd')<'3/20'){
ui.alert("Winter")
}
I would repeat this obviously for other seasons.
My expectation is that 1/13/2023 evaluates to 1/13 by (Utilities.formatDate(myDate, "GMT", 'MM/dd') and falls with the range.
That is not happening
Thanks in advance.
Here is an example of comparing today's date with the season.
function getSeason() {
try {
// per Farmers Almanac
let season = ["Winter","Spring","Summer","Fall"];
let seasons = [["12/21/2021","3/20/2022","6/21/2022","9/22/2022","12/21/2022","3/20/2023"],
["12/21/2022","3/20/2023","6/21/2023","9/23/2023","12/21/2023","3/20/2024"],
["12/21/2023","3/19/2024","6/20/2024","9/22/2024","12/21/2024","3/20/2025"],
["12/21/2024","3/20/2025","6/20/2025","9/22/2025","12/21/2025","3/20/2026"],
["12/21/2025","3/20/2026","6/21/2026","9/22/2026","12/21/2026","3/20/2027"]];
let today = new Date();
let year = today.getFullYear()-2022;
today = new Date(today.getFullYear(),today.getMonth(),today.getDate());
let found = seasons[year].findIndex( (date,index) => {
return today >= new Date(date) && today < new Date(seasons[year][index+1]);
}
);
console.log(today);
console.log(season[found])
}
catch(err) {
console.log(err);
}
}
12:20:50 PM Notice Execution started
12:20:50 PM Info Mon Sep 12 2022 00:00:00 GMT-0700 (Pacific Daylight Time)
12:20:50 PM Info Summer
12:20:50 PM Notice Execution completed
Reference
Date object
Array.findIndex()
Season of the year:
function seasonOfTheYear(date) {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Sheet0");
const ds = sh.getDataRange().getValues();
const sObj = { pA: [] };
ds.forEach(s => {
sObj[new Date(s[1]).valueOf()] = { start: new Date(s[1]), season: s[0] };
sObj.pA.push(new Date(s[1]).valueOf());
});
let dv = new Date(date).valueOf();
let ssn = sObj.pA.reduce((a, c, i) => {
if (dv >= c && dv < sObj.pA[(i + 1) % sObj.pA.length]) {
a["season"] = sObj[c].season;
}
return a;
}, {season:''}).season;
Logger.log(ssn);
}
I got this data from timeandate.com and put it into Sheet0
A
B
SPRING
Tuesday, March 1
SUMMER
Wednesday, June 1
FALL
Thursday, September 1
WINTER
Thursday, December 1

Using moment to calculate the number of days between 2 dates

I'm trying to work out the number of days between 2 dates in Javascript with the following code.
console.log(self.StartDate());
var start = moment(self.StartDate(), "YYYY-MM-DD");
console.log(start);
console.log(self.EndDate());
var end = moment(self.EndDate(), "YYYY-MM-DD");
console.log(end);
var duration = moment.duration(start.diff(end));
console.log(duration);
//no of days between start and end
console.log(duration.asDays());
console output:
Thu Jun 20 2019 01:00:00 GMT+0100 (British Summer Time)
n {_isAMomentObject: true, _i: Thu Jun 20 2019 01:00:00 GMT+0100 (British Summer Time), _f: "YYYY-MM-DD", _isUTC: false, _pf: {…}, …}_d: Wed Aug 19 0020 00:00:00 GMT-0001 (British Summer Time) {}_f: "YYYY-MM-DD"_i: Thu Jun 20 2019 01:00:00 GMT+0100 (British Summer Time) {}_isAMomentObject: true_isUTC: false_locale: r {_ordinalParse: /\d{1,2}(th|st|nd|rd)/, ordinal: ƒ, _abbr: "en", _ordinalParseLenient: /\d{1,2}(th|st|nd|rd)|\d{1,2}/}_pf: {empty: false, unusedTokens: Array(0), unusedInput: Array(3), overflow: 1, charsLeftOver: 49, …}__proto__: Object
Mon Jun 24 2019 15:10:41 GMT+0100 (British Summer Time)
n {_isAMomentObject: true, _i: Mon Jun 24 2019 15:10:41 GMT+0100 (British Summer Time), _f: "YYYY-MM-DD", _isUTC: false, _pf: {…}, …}
Ea {_milliseconds: -126230400000, _days: 0, _months: 0, _data: {…}, _locale: r}
-1461
self.StartDate() is 20/06/2019 and self.EndDate() is 24/06/2019 so I'm exciting the alert to display 4 however it displays -1461.
Why is this the case?
The problem is that your dates are not formatted the way you tell moment.js they are. 20/06/2019 is DD/MM/YYYY and not YYYY-MM-DD. As per the documentation, non-numeric characters are ignored so 20/06/2019 would be parsed as 2006-20-19. Since such a date does not exist, Moment.js tries to guess what you actually meant and it comes up with 2020-06-19:
var start = moment("20/06/2019", "YYYY-MM-DD");
console.log(start);
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>
Same thing happens with the end date.
You need to either change the format you tell to Moment.js or fix the start and end dates to use the format you specified, in both cases, you'd get the correct result:
var self = {
StartDate: () => "20/06/2019",
EndDate: () => "24/06/2019"
}
var start = moment(self.StartDate(), "DD/MM/YYYY"); //using the correct format
var end = moment(self.EndDate(), "DD/MM/YYYY");
var duration = moment.duration(start.diff(end));
console.log(duration.asDays());
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>
var self = {
StartDate: () => "2019-06-20", //using dates in the correct format
EndDate: () => "2019-06-24"
}
var start = moment(self.StartDate(), "YYYY-MM-DD");
var end = moment(self.EndDate(), "YYYY-MM-DD");
var duration = moment.duration(start.diff(end));
console.log(duration.asDays());
<script src="https://cdn.jsdelivr.net/momentjs/2.14.1/moment-with-locales.min.js"></script>
Your code should work perfectly fine. You should only swap start and end at the defference calculation to get positive values.
var startDate = moment("2019-06-20", "YYYY-MM-DD");
var endDate = moment("2019-06-24", "YYYY-MM-DD");
var duration = moment.duration(startDate.diff(endDate));
//no of days between start and end
console.log(duration.asDays());
var duration = moment.duration(endDate.diff(startDate));
console.log(duration.asDays());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
If you are only interested in the difference calculated in days, this code will be shorter:
var startDate = moment("2019-06-20", "YYYY-MM-DD");
var endDate = moment("2019-06-24", "YYYY-MM-DD");
var diff = startDate.diff(endDate, 'days');
console.log(diff);
var diff = endDate.diff(startDate, 'days');
console.log(diff);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
There has to be some issue with the dates themselves.
And in fact, it's the way you parse the date strings
// This is parsed as the 19th day of 6th month in year 2020
var startDate = moment("20/06/2019", "YYYY-MM-DD");
// This is parsed as the 19th day of 6th month in year 2024
var endDate = moment("24/06/2019", "YYYY-MM-DD");
var diff = endDate.diff(startDate, 'days');
console.log({"start": startDate, "end": endDate, "diff": diff});
// You either need to change the date strings or the format strings
var startDate = moment("20/06/2019", "DD/MM/YYYY");
var endDate = moment("24/06/2019", "DD/MM/YYYY");
var diff = endDate.diff(startDate, 'days');
console.log({"start": startDate, "end": endDate, "diff": diff});
// You either need to change the date strings or the format strings
var startDate = moment("2019-06-20", "YYYY-MM-DD");
var endDate = moment("2019-06-24", "YYYY-MM-DD");
var diff = endDate.diff(startDate, 'days');
console.log({"start": startDate, "end": endDate, "diff": diff});
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.js"></script>
Your date is invalid, you specified a start date of "20/06/2019" which is a template of "DD/MM/YYYY", but told moment to use the template of "YYYY-MM-DD".
You simply need to replace the template that you pass to moment, and here is a bit cleaner way to do it:
const DEFAULT_DATE_TEMPLATE = "DD/MM/YYYY";
const getDaysBetweenDates = (date1, date2, dateTemplate = DEFAULT_DATE_TEMPLATE) => {
const start = moment(date1, dateTemplate);
const end = moment(date2, dateTemplate);
const duration = moment.duration(start.diff(end));
const daysDiff = duration.asDays();
// for your example you will get -4, abs will make it into 4 for you
return Math.abs(daysDiff);
}
const myDiff = getDaysBetweenDates('20/06/2019', '24/06/2019');
console.log(myDiff); // 4
// or if you rather keep your other template
const myDiff2 = getDaysBetweenDates('2019-06-20', '2019-06-24', 'YYYY-MM-DD');
console.log(myDiff2); // 4

new Date can't give me right time

startDate = "2019-03-07 (목) 12:00";
var year = startDate.slice(0,4);
var month = startDate.slice(5,7);
var day = startDate.slice(8,10);
var hour = startDate.slice(15,17);
var minute = startDate.slice(18,20);
var selEndDatetime = new Date(year, month, day, hour, minute);
console.log(selEndDatetime);
I want to see "Tue Mar 07 2019 12:00:00 GMT+0900 (한국 표준시)", but console shows me the message "Sun Apr 07 2019 12:00:00 GMT+0900 (한국 표준시)".
What is wrong this code and how can I modify it to get the desired output?
The month starts at 0. You need to parse month from string to integer and minus 1 when creating a date instance.
startDate = "2019-03-07 (목) 12:00";
var year = startDate.slice(0,4);
var month = parseInt(startDate.slice(5,7))
var day = startDate.slice(8,10);
var hour = startDate.slice(15,17);
var minute = startDate.slice(18,20);
var selEndDatetime = new Date(year, month - 1, day, hour, minute);
console.log(selEndDatetime);
You can simply pass the startDate string as an argument to the Date in order to create selEndDatetime
Code:
const startDate = '2019-03-07 (목) 12:00';
const selEndDatetime = new Date(startDate);
console.log(selEndDatetime);

ReactJS Moment is not formatting date correctly

I have a function for displaying the first date of the week and it's result are displayed as followed:
Mon Nov 12 2018 08:14:09 GMT-0600 (Central Standard Time)
...what am attempting to do is display the result with the month only:
2018-11-12
...here is the function for getting the first day of the week:
let sd = new Date();
const startOfWeek = (date) => {
let diff = date.getDate() - date.getDay() + (date.getDay() === 0 ? -6 : 1);
return new Date(date.setDate(diff));
}
...I call the function as followed:
const startDay = startOfWeek(sd).toString();
...Here is where I Use moment to apply the formatting:
moment(startDay).format('YYYY MMMM Do');
...but my date still displays the following:
Mon Nov 12 2018 08:14:09 GMT-0600 (Central Standard Time)
...could I get some help as to what am doing wrong?
I think the moment js format you are looking for is:
moment(startDay).format('YYYY-MM-DD');
The format YYYY MMMM Do would return a string like: "2018 November 13th".
This should work, the format was incorrect though, it should be YYYY-MM-D
let sd = new Date();
const startOfWeek = (date) => {
let diff = date.getDate() - date.getDay() + (date.getDay() === 0 ? -6 : 1);
return new Date(date.setDate(diff));
}
const startDay = startOfWeek(sd)
console.log(moment(startDay).format('YYYY-MM-D'));

How to list all month between 2 dates with moment.js?

I've two dates
2015-3-30 2013-8-31
How can I make a month list like:
[ '2015-3', '2015-2', '2015-1', '2014-12', '2014-11', '2014-10', '2014-09', '2014-08', '2014-07', '2014-06', '2014-05'....., '2013-08' ]
Thanks.
This should do it:
var startDate = moment('2021-12-31');
var endDate = moment('2022-12-14');
var betweenMonths = [];
if (startDate < endDate){
var date = startDate.startOf('month');
while (date < endDate.endOf('month')) {
betweenMonths.push(date.format('YYYY-MM'));
date.add(1,'month');
}
}
I think the original answer isn't entirely correct, as you wouldn't get '2015-3' in your array. This is due to the fact your start date would eventually end up as '2015-3-31' and would fail the conditional in place. You could extend it like below.
UPDATE: I've now included cloning the dateStart variable so it isn't mutated at all.
var dateStart = moment('2013-8-31');
var dateEnd = moment('2015-3-30');
var interim = dateStart.clone();
var timeValues = [];
while (dateEnd > interim || interim.format('M') === dateEnd.format('M')) {
timeValues.push(interim.format('YYYY-MM'));
interim.add(1,'month');
}
You could try with this example
var one = moment("2015-3-30");
var two = moment("2014-8-31");
var dateDiffs = [];
var count = Math.round(moment.duration(one.diff(two)).asMonths());
month = two.month() + 1;
year = two.year();
for (var i=1; i<=count; i++) {
if (month > 12) {
month = 1;
year++;
}
dateDiffs.push(year+"-"+month);
console.log(month);
month++;
}
console.log(dateDiffs);
You are using multiple formats in the output: YYYY-MM and YYYY-M, so I picked the first. You can edit as you see fit.
var startDateString = "2012-5-30";
var endDateString = "2015-8-31";
var startDate = moment(startDateString, "YYYY-M-DD");
var endDate = moment(endDateString, "YYYY-M-DD").endOf("month");
var allMonthsInPeriod = [];
while (startDate.isBefore(endDate)) {
allMonthsInPeriod.push(startDate.format("YYYY-MM"));
startDate = startDate.add(1, "month");
};
console.log(allMonthsInPeriod);
document.getElementById("result").innerHTML = allMonthsInPeriod.join("<br />");
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js"></script>
<div id="result"></div>
const getMonths = (start, end) =>
Array.from({ length: end.diff(start, 'month') + 1 }).map((_, index) =>
moment(start).add(index, 'month').format('MM.YYYY'),
);
const months = getMonths(moment('01.2019','MM.YYYY'),moment('01.2020','MM.YYYY'))
console.log(months)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.4/moment.min.js"></script>
This is the best way in my opinion.
const startDate = moment('2013-8-31', 'YYYY-M-DD');
const endDate = moment('2015-3-30', 'YYYY-M-DD');
const months = [];
const flag = startDate;
while (flag.diff(endDate) <= 0) {
months.push(flag.format('YYYY-M'));
flag.add(1, 'M');
}
Why don't you just https://date-fns.org/v2.13.0/docs/eachMonthOfInterval ??
// Each month between 6 February 2014 and 10 August 2014:
var result = eachMonthOfInterval({
start: new Date(2014, 1, 6),
end: new Date(2014, 7, 10)
})
//=> [
// Sat Feb 01 2014 00:00:00,
// Sat Mar 01 2014 00:00:00,
// Tue Apr 01 2014 00:00:00,
// Thu May 01 2014 00:00:00,
// Sun Jun 01 2014 00:00:00,
// Tue Jul 01 2014 00:00:00,
// Fri Aug 01 2014 00:00:00
// ]

Categories