FullCalendar V4 - How to account for shorter months in a recurring event series? - recurring-events

I'm using FullCalendar v4-alpha-3 with the RRule plugin to generate recurring events. It works as expected with only one problem: how do I modify a recurring event to account for months with fewer days than the starting month in a series?
For example, if the first monthly occurrence happens on January 29, 2019; the event will be repeated on the 29th of all subsequent months except in February since it only has 28 days (leap years excluded).
I've tried resetting dtstart to the first day of the following month. It works, except the event is no longer recursive.
Here's a stripped down snippet of my setup:
let calendar = new Calendar(calendarEl, {
plugins: [ rrulePlugin ],
events: [
{
rrule: 'DTSTART:20190129 RRULE:FREQ=MONTHLY;UNTIL=20200130;COUNT=13;BYMONTHDAY=29'
}
],
eventRender: function(info) {
...
// reset start date to the first day of the following month
// if current month has fewer days than base month
let start = event.start;
let day = start.getDate();
let now = new Date();
let currentMonth = now.getMonth();
let currentYear = now.getFullYear();
let daysInCurrent = getDaysInMonth(currentMonth + 1, currentYear);
let nextStart = start;
if (day > daysInCurrent) {
nextStart = new Date(currentYear, currentMonth + 1, 1);
event.setStart(nextStart);
event.setEnd(null);
}
}
});
I'd appreciate any insight.

Not quite the solution I hoped for, but RRule's bysetpos property seems to offer the next best alternative as it allows for a fallback date in case the one specified doesn't exist.
For example, the following would generate an occurrence on the 30th of every month; or the last day of the month if the 30th doesn’t exist:
FREQ=MONTHLY;BYMONTHDAY=28,29,30;BYSETPOS=-1.
Sourced from: https://icalevents.com/2555-paydays-last-working-days-and-why-bysetpos-is-useful/

I know this is an old question but maybe this will be usefull for someone:
I'm using momentjs library
monthly:
let endofmonth = moment('2020-02-29', "YYYY-MM-DD").endOf('month').format('DD');
let curday = moment('2020-02-29, "YYYY-MM-DD").format('DD');
single_event.title = title;
single_event.rrule = {};
single_event.rrule.freq = 'monthly';
single_event.rrule.dtstart = start_date;
single_event.rrule.interval = reminder_interval;
single_event.rrule.count = reminder_count;
if(endofmonth == curday){
// Checking if given day of the month is last
single_event.rrule.byweekday = ['mo','tu','we','th','fr','sa','su'];
single_event.rrule.bysetpos = -1;
}
else{
single_event.rrule.bymonthday = parseInt(curday);
}
calendar_events.push(single_event);
var calendar = new FullCalendar.Calendar(calendarEl, {
...
events: calendar_events
});
yearly:
single_event.title = title;
single_event.rrule = {};
single_event.rrule.dtstart = start_date;
single_event.rrule.count = parseInt(reminder_count);
if(endofmonth == curday){
// Checking if given day of the month is last
single_event.rrule.freq = 'monthly'; // Will work as yearly if interval is 12
single_event.rrule.interval = parseInt(reminder_interval)*12;
single_event.rrule.bymonthday = [28,29,30,31];
single_event.rrule.bysetpos = -1;
}
else{
single_event.rrule.freq = 'yearly';
single_event.rrule.bymonthday = parseInt(curday);
}
calendar_events.push(single_event);
var calendar = new FullCalendar.Calendar(calendarEl, {
...
events: calendar_events
});

Related

Moment JS seemingly returning random date

Moment JS is returning a random date.
I am trying to create a calendar in a react-native project. I created this loop to count back the days from today's date. I have attached my console and tried to clearly show how I tried to debug this.
The subtract method seems not to recognise the loop and the i value seems to stay at 16.
Any help would be greatly appreciated.
This is the code that is causing all the fussThis is the output in the console
Per Moment.js, moments are mutable. Clone the moment before performing date math
https://momentjs.com/guides/#/lib-concepts/mutability/
You'll need to create a new moment instance or clone the existing one when performing operations like .add(), .subtract(), etc.
const moment = require("moment");
const today = moment();
// count back N days
const N = 3;
let i = 1;
let days = [];
// #1 - Create a new moment instance from today and add -i days
while (i <= N) {
const day = moment(today).add(-i, "days");
days.push(day);
i++;
}
console.log("Approach #1");
console.log({ days });
// #2 - A moment is mutable. So we use add() to mutate today by -1 days each iteration, clone the instance, and push to array
i = 0;
days = [];
while (i < N) {
const day = today.add(-1, "days").clone();
days.push(day);
i++;
}
console.log("Approach #2");
console.log({ days });

FullCalendar VueJS - Update date range

I use the official FullCalendar VueJS component, and I would like to update the current range displayed in the view (DayGridMonth here) : 1 month, 2 months, 3 months, custom period
According to the "documentation", the visibleRange property can be updated thanks to the function setOption() (https://fullcalendar.io/docs/visibleRange), but it doesn't work for me : the property is well updated in component, but the view wasn't updated.
I also tried to update state manually, without result.
This is my draft function to do this
updateCurrentDate: function () {
const calendarApi = this.$refs.fullCalendar.getApi();
const date = new Date(calendarApi.getDate());
let endRange;
this.currentPeriodRange = calendarApi.state.dateProfile.activeRange;
this.currentPeriodLabel = moment(date).format('MMMM YYYY');
if (this.currentView === 'month') {
endRange = moment(this.currentPeriodRange.start).add(2, 'month');
this.currentPeriodRange.end = endRange.toDate();
// Not working
calendarApi.setOption('visibleRange', this.currentPeriodRange);
// No one of these test work
calendarApi.state.dateProfile.activeRange = this.currentPeriodRange; //
calendarApi.state.dateProfile.currentRange = this.currentPeriodRange;
calendarApi.state.dateProfile.renderRange = this.currentPeriodRange;
}
if (this.currentPeriodRange.start !== this.currentPeriodRange.end) {
this.currentPeriodLabel = this.currentPeriodLabel + ' - ' + endRange.format('MMMM YYYY');
}
return;
},
Thanks for reading and answering

How to prevent user to enter specific times in datetimepicker?

I am using angular-bootstrap-datetimepicker. I know how to restrict the user from entering specific dates.
$dates.filter(function(date){
return (date.localDateValue() <= new Date().valueOf()-(24*60*60*1000));
}).forEach(function(date){
date.selectable = false;
})
This code insode startDateBefore render, prevents user from entering dates 24h past the current date.
But now I want users to enter spectic times only. Like user can select only times between 10:05am to 11:10pm. I am unable to do that. Documentation doesn't specify on how to add filter to hour and minutes. Any help on that.
In Angular Date Time Picker, the beforeRender function also takes parameter called view. So we can use the view==='hour' to restrict users from entering past hours. I was missing the code for hours.
function startDateBeforeRender ($view, $dates, $leftDate, $upDate, $rightDate) {
var today = moment().valueOf();
$dates.filter(function (date) {
return date.localDateValue() < today -(24*60*60*1000)
}).forEach(function (date) {
date.selectable = false;
});
// to restrict hours by admin
if ($view === "hour") {
// restict previous hours
$dates.filter(function (date) {
return date.localDateValue() < today
}).forEach(function (date) {
date.selectable = false;
})
}
}
date = new Date().valueOf();
if( date > 1000*(10*60+5) ){
if( date < 1000*(23*60+10) ){
//Code green, I repeat, CODE GREEN!
}
}

Javascript Age Comparison

basically I am setting up a age verification script for a alcohol company and each country of course has a specific age to consume or buy alcohol.
I have set up the basics just now but I am running in to a problem. Right now I want to be able to gather there DOB using the input fields. Convert this to a date and them somehow compare it to the legal drinking age of the country in question.
Unfortunately testing the DOB is proving difficult and I know it is a problem with the event handler I am using as it won't output my required result to the console.
If anyone could help that would be fantastic.
Here is a link to my fiddle.
var countries = {
"Albania": 18,
"Algeria": 18,
"Argentina": 21,
"Armeria": 18,
"Australia": 18,
"Austria": 18
};
var individualCountry;
var day;
var month;
var year;
$("#verify").submit(function() {
day = $("#day").val();
month = $("#month").val();
year = $("#year").val();
var fullDate = day + month + year;
console.log(fullDate);
individualCountry = $("#countries").val();
var ageLimit = countries[individualCountry];
if (personsAge >= ageLimit) {
}
})
https://jsfiddle.net/h989qrLs/
try this code
function_calculateAge(birthday) { // birthday is a date
var ageDifMs = Date.now() - birthday.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch
return Math.abs(ageDate.getUTCFullYear() - 1970);
}
for more details open this link by André Snede Hansen

Difference between datepickers except sundays in infopath

How to get the no of days between two date picker controls in info path except sundays?
If It is possible let me know.
Thanks in advance.........
Using custom code you can do it easily. In this case I'm calculating the number of days (except Sundays) between a given date and today's date.
var navigator = this.MainDataSource.CreateNavigator();
string startDate = navigator.SelectSingleNode("/my:myFields/my:date_start", NamespaceManager).Value;
DateTime startDateTime = DateTime.ParseExact(startDate, "yyyy-MM-dd", null);
DateTime today = DateTime.Today;
int count = 0;
while (startDateTime > today)
{
today = today.AddDays(1);
if (today.DayOfWeek != DayOfWeek.Sunday)
{
count++;
}
}
I hope it helps