Using .addDateExclusion() - google-apps-script

I'm creating school class calendar with repeating events, how do I use .addDateExclusion(new Date()), I tried a lot of combinations none of witch worked
function makeCalendar(name, begin, end, calendar) {
var eventSeries = CalendarApp.getCalendarById(calendar).createEventSeries(
name,
begin,
end,
CalendarApp.newRecurrence()
.addDateExclusion(new Date(2019, 1, 5, 0, 0, 0, 0))
.addWeeklyRule().interval(2).until(krajdat)
);
}
EDIT 1:
This is only ting that actually worked
function makeCalendar(name, begin, end, calendar) {
var eventSeries = CalendarApp.getCalendarById(calendar).createEventSeries(
name,
begin,
end,
CalendarApp.newRecurrence()
.addDateExclusion(begin)
.addWeeklyRule().interval(2).until(krajdat)
);
}
code above does what it is supposed to do that is ignore first occurrence, but whatever I did to that date like adding days didn't work
EDIT 2:
var d = new Date(begin);
d.setMonth(9);
d.setDate(9);
var eventSeries = CalendarApp.getCalendarById(calendar).createEventSeries(
name,
begin,
end,
CalendarApp.newRecurrence()
.addDateExclusion(d)
.addWeeklyRule().interval(2).until(krajdat)
);
This actually worked, but setting full year didn't.
Still not optimal result because I want to pass recurrence to function, but we are getting somewhere.
EDIT 3:
I think the problem here are actually time zones, I looked the logs and that was the only difference between working and non working dates.

Found error, problem were time zones that i needed to set in preferences .addDateExclusion() doesn't work if used with different time zones.

Related

Expression.Error: A cyclic reference was encountered during evaluation. - using custom function NetWorkDays in Power Query

I have created a custom function from a blank query to calculate the number of days excluding holidays and the weekends, the function is below
Query1 = (StartDate as date, EndDate as date) as number =>
let
DateList = List.Dates(StartDate, Number.From(EndDate - StartDate) , #duration(1, 0, 0, 0)),
RemoveWeekends = List.Select(DateList, each Date.DayOfWeek(_, Day.Monday) < 5),
RemoveHolidays = List.RemoveItems(RemoveWeekends, Holidays),
CountDays = List.Count(RemoveHolidays)
in
CountDays,
Custom1 = Query1
in
Custom1
Everything is working in the file on my computer, but the issue is when anyone else from my team is trying to use the file with queries there. We are getting error <Expression.Error: A cyclic reference was encountered during evaluation.>
I've tried to trace steps and find out when the error is occurring and it's always pointing at the custom function.
Please help me, I need to fix it asap so my team can use this.
Function screen
Calendar before function
Calendar after function
I was using this youtube guide to create function: https://www.youtube.com/watch?v=e2ic432NvhY
try changing your function to
(StartDate as date, EndDate as date) as number =>
let DateList = List.Dates(StartDate, Number.From(EndDate - StartDate) , #duration(1, 0, 0, 0)),
RemoveWeekends = List.Select(DateList, each Date.DayOfWeek(_, Day.Monday) < 5),
RemoveHolidays = List.RemoveItems(RemoveWeekends, Holidays),
CountDays = List.Count(RemoveHolidays)
in CountDays
then, assuming Holidays is a query with some list of dates like
= {#date(2022,6,15),#date(2022,1,18)}
then
= Table.AddColumn(#"Changed Type", "Custom", each NetWorkDays([StartDate],[EndDate]))
works fine
Thanks everyone for such quick answers.
My issue was that first I've created custom function based on list of holidays and calendar and then i've used it in calendar as well. When I removed custom function from the calendar query, leaving only starting date of the week, ending date and week number it started to work again.

Spoof JSON (or other resource) while loading realtime Web site

I'm trying to write a userscript for a friend. The Website I'm writing it for (app.patientaccess.com) tells you what doctors appointments you have, (among other things). However, in order to write my userscript, I need to know how the app handle appointments for the following year.
At the moment, the only way to know is to wait until the end of the year when my friend starts making appointments for the following year. Since it's an Angular app, I'd rather, if possible, point it to a fabricated JSON file of my creation when the app requests that particular data. In that file I can give it some data for this year and next year and then I can see what happens with appointments made for the following year.
I'm hoping this can be done with an addon for Chrome or Firefox or perhaps some kind of free/open source software.
Thanks in advance.
I came up with a function that will accurately guess there year, given the day name, date and month, if it's within a couple of years either side of the current year.
function calculateYear(dayName, dayOfMonth, monthNum, returnDateObj) {
monthNum -= 1;
maxIterations = 3;
var startYear = (new Date()).getFullYear();
var dateObj = new Date(startYear, monthNum, dayOfMonth);
for (var i = 0; i < maxIterations; i++) {
dateObj.setYear(startYear + (1 * i));
if (dayName == daysOfTheWeek[dateObj.getDay()]) {
return (returnDateObj) ? dateObj : dateObj.getFullYear();
}
dateObj.setYear(startYear - (i + 1));
if (dayName == daysOfTheWeek[dateObj.getDay()]) {
return (returnDateObj) ? dateObj : dateObj.getFullYear();
}
}
return 'No Match';
}
It works a treat, as you can see here.

Is a "Try / Except ValueError UNLESS" possible?

I'm new to python and have been trying like hell for the past few hours to figure out how to get this to work properly...
It's very simple code I'm sure, but I'm just not getting it.
It should be pretty self-explanatory below in the code, but basically I'm asking a user to input the date of an event as an 'int' and if it's not a number, then ask them to try again... UNLESS it's a "?"
while True:
date = None
street = str(input('Name of street?: ').title())
city = str(input("In what city?: ").title())
while True:
try:
year = int(input("Date of event? (or '?'): "))
if date == "?":
break
except Exception:
print("That's not a date, try again!")
continue
break
It seems that it's not even getting to see IF because it gets caught by the 'except' before it can.
If you're going to display help or something when a '?' is input, then just call the function to display the help where you have the break currently.
if date == "?":
display_help()
continue
Then, split reading the input and processing it into two steps.
in = input("Date of event? (or '?'): ")
if in == "?":
display_help()
continue
year = int(in)
Also, you ask for a date but then assume that a year is entered, I'd be more explicit in your promt.
"Please enter the year of the event, ex: 1998"
or whatever form you actually want it in.
Trying using a valueError exception. Also I think in your post you mentioned you wanted to enter a date as integer, so I replaced year with the date. If you wanted the year to be an integer you can replace the variable date with year. If you wanted to the user to enter a year, day and month then this program needs to be redesigned a bit.
date = None
street = str(input('Name of street?: ').title())
city = str(input("In what city?: ").title())
while True:
date = input("Date of event? (or '?'): ")
if date == "?":
break
else:
try:
date = int(date)
except ValueError:
print("That's not a date, try again!")
continue
break

How to sort objects in DOORS by modification TIME, not just mod DATE?

Sorting objects in DOORS by the built-in DXL Attribute "Last Modified On" only sorts to the date level. That is, after sorting there is no guarantee to the order of Objects that were modified on the same calendar date (but at different times).
That's beyond stupid, especially since other online sources suggest that this field does in fact have this information available - but apparently only sorts on the displayed info, not the underlying data.
Neverminding how I'd LIKE this to work, what can I do instead? Today a module has literally hundreds of changed Objects, but I'm only interested in those altered in the last hour.
Looks like DOORS stores Last Modified On as a date only, without any time. Just to check, I added a layout DXL column with this in it:
Date dMod
dMod = obj."Last Modified On"
dMod = dateAndTime(dMod)
display dMod ""
In return I was greeted with entries like:
09/08/15 00:00:00
I'm not really proud of this next thing, but it sort of does the job. I created a DXL attribute called Last History Date with the following DXL:
History hr
Date dResult = null
Date dHist = null
Date dLastMod = null
dLastMod = obj."Last Modified On"
dLastMod = dateAndTime(dLastMod)
for hr in obj do {
dHist = hr.date
}
if (null dHist) { dResult = dLastMod }
else if (dLastMod > dHist) { dResult = dLastMod }
else { dResult = dHist }
obj.attrDXLName = dResult
If there are no history records, or history is recorded before Last Modified On, it just uses Last Modified On and you'll have to deal with 00:00:00. The history date isn't necessarily the same as Last Modified On -- depends on if you have "Affect change dates" or "Generate history" features turned on for the various object attributes. It's sort of a half-baked solution, but if you really want to sort with time I can't think of another way.

How do I create a SQL calendar with reccuring events that can be easily queried?

I checked several older questions regarding this topic like this one: Calendar Recurring/Repeating Events - Best Storage Method however, the answers are pretty bad performance-wise and cumbersome in implementation. From another answer, it's easy to tell why the accepted answer is a bad idea: a month of events takes 90 queries. Which is unacceptable.
Anyways, here's the issue I'm facing so that you don't have re-read those questions:
Storing events in such a way to allow them to recur. Think Google Calendar where you can specify patterns like "happens on the 1st of the month, every month" or "happens every 2nd monday of the month" (the latter is less important to me.
Querying a list of events for a time period. For example, I want to show someone a list of events for the next 2 months and I don't want to query for every single day of the month. Doing that would just kill the server (per user among thousands of rows of events)
DB agnostic. I use PgSQL and saw many answers for this question on other forums using either MS SQL-specific stuff or Oracle.
I'd appreciate any help! I read a couple of papers on the topic and still can't find something I can make work in SQL specifically.
The solution I have come up with is that I have an event table that has five fields defining the recurrence of the event, as defined below. I then also have a schedule table which I populate with the actual occurrence of the events. I do require an end date, and even when they specify something to go out to a couple years out, it is a monthly type event which does not create that many entries into the schedule table.
So, the event is stored in an event table, with a startDateTime and an endDateTime that describe the entire duration of the event if there is no recurrence. These two datetime fields also define the overall start and end of the event if it is a recurring event. In that same event table, we have the five fields defining recurrence, as laid out below.
The Schedule table stores individual occurrences of each event. So it has an eventId, startDateTime, and endDateTime. This start and end refer only to each occurrence, not the overall span.
For querying for all the scheduled occurrences happening in a period of time, I just query the schedule table checking for any occurrences that match this condition:
select * from schedule where schedule.startDateTime < #queryPeriodEnd and schedule.endDateTime > #queryPeriodStart
This query gives me only the schedule entries that happen partially or wholly within my query period. For getting the event data, it's a simple matter of joining to the event table.
The interesting part is calculating something like the second thursday of the month. That happens in the actual code for figuring out all the scheduled occurrences for a given event. I am also enclosing my code for that below.
EVENT RECURRENCE FIELDS
recurs
0=no recurrence
1=daily
2=weekly
3=monthly
recurs_interval
this is how many of the periods between recurrences. If the event recurs every 5 days, recurs_interval will have a 5 and recurs will have 1. If the event recurs every 3 weeks, recurs_interval will have a 3 and recurs will have a 2.
recurs_day
If the user selected monthly type recurrence, on a given day of the month (ex: 10th or the 14th). This has that date. The value is 0 if the user did not select monthly or specific day of month recurrence. The value is 1 to 31 otherwise.
recurs_ordinal
if the user selected a monthly type recurrence, but an ordinal type of day (ex: first monday, second thursday, last friday). This will have that ordinal number. The value is 0 if the user did not select this type of recurrence.
1=first
2=second
3=third
4=fourth
5=last
recurs_weekdays
for weekly and monthly-ordinal recurrence this stores the weekdays where the recurrence happens. 1=Sunday
2=Monday
4=Tuesday
8=Wednesday
16=Thursday
32=Friday
64=Saturday
So, every 4 weeks on Saturday and Sunday would be
recurs=2, recurs_interval=4, recurs_weekdays=65 (64 + 1)
Similarly, Every three months on the first Friday of the month would be
recurs=3, recurs_interval=3, recurs_ordinal=1, recurs_weekdays=32
CODE
thisEvent.occurrences = new List<ScheduleInstance>();
DateTime currentDateTime = (DateTime) thisEvent.start;
DateTime currentEndTime;
BitArray WeekDayRecurrenceBits = new BitArray(new Byte[] {(Byte) thisEvent.recursWeekdays});
while (currentDateTime < thisEvent.end)
{
currentEndTime = new DateTime(currentDateTime.Year, currentDateTime.Month, currentDateTime.Day,
thisEvent.end.Value.Hour, thisEvent.end.Value.Minute, thisEvent.end.Value.Second);
switch (thisEvent.recurs)
{
case (RecurrenceTypeEnum.None):
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
currentDateTime = (DateTime)thisEvent.end;
break;
case (RecurrenceTypeEnum.Daily):
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
currentDateTime = currentDateTime.AddDays(thisEvent.recursInterval);
break;
case (RecurrenceTypeEnum.Weekly):
int indexIntoCurrentWeek = (int) currentDateTime.DayOfWeek;
while ((indexIntoCurrentWeek < 7) && (currentDateTime < thisEvent.end))
{
if (WeekDayRecurrenceBits[(int) currentDateTime.DayOfWeek])
{
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
}
currentDateTime = currentDateTime.AddDays(1);
currentEndTime = currentEndTime.AddDays(1);
indexIntoCurrentWeek++;
}
currentDateTime = currentDateTime.AddDays(7 * (thisEvent.recursInterval - 1));
break;
case (RecurrenceTypeEnum.Monthly):
if (thisEvent.recursDay == 0)
{
DateTime FirstOfTheMonth = new DateTime(currentDateTime.Year, currentDateTime.Month, 1);
int daysToScheduleOccurrence = ((thisEvent.recursWeekdays - (int)FirstOfTheMonth.DayOfWeek + 7) % 7)
+ ((thisEvent.recursOrdinal - 1) * 7)
- currentDateTime.Day + 1;
if (daysToScheduleOccurrence >= 0)
{
currentDateTime = currentDateTime.AddDays(daysToScheduleOccurrence);
currentEndTime = currentEndTime.AddDays(daysToScheduleOccurrence);
if (currentDateTime < thisEvent.end)
{
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
}
}
}
else
{
if (currentDateTime.Day <= thisEvent.recursDay && thisEvent.recursDay <= DateTime.DaysInMonth(currentDateTime.Year, currentDateTime.Month) )
{
currentDateTime = currentDateTime.AddDays(thisEvent.recursDay - currentDateTime.Day);
currentEndTime = currentEndTime.AddDays(thisEvent.recursDay - currentEndTime.Day);
AddOccurrenceToRooms(thisEvent, currentDateTime, currentEndTime);
}
}
currentDateTime = currentDateTime.AddDays((currentDateTime.Day - 1) * -1).AddMonths(thisEvent.recursInterval);
break;
default:
break;
}
}