iCalendar (RFC5545) recurrence rule for year - icalendar

How can I make an event occur every year for some selected days, Like starting 45 days then skip 15 days, then select 30 days then skip 30 days, then select 30 days then skip 30 days, then select 30 days then skip 30 days,then select 30 days then skip 30 days,then select 30 days then skip 30 days
RRULE:FREQ=YEARLY;BYYEARDAY=1,2,..,45,61,62,...,90,120,121....
Is this the right procedure?

combination of freq=yearly and byyearday is indeed the way forward, though it does not look ot be the case for you, you could also consider BYWEEKNO.

Related

Redshift how to subtract the number of minutes from two different date columns

I would like to subtract two date columns and get the difference in minutes. Based on the table below, we can see that a notification has an ideal_date of 11/29 1pm and we noticed that the actual_date was sent on 12/30 1pm that means that it took 24 hours for the notification to be sent, meaning it took 1440 minutes for the notification to be sent out.
I tried the following query but I'm not getting what I need.
select n.ideal_date,
n.actual_date,
abs(date_part(minute,n.ideal_date) - date_part(minute,n.actual_date)) as minutes
from table_date n
id
ideal_date
actual_date
minutes
58
12/29/2021,1:00pm
12/30/2021, 1:00pm
1440 mins
You want DATEDIFF(). https://docs.aws.amazon.com/redshift/latest/dg/r_DATEDIFF_function.html
select n.ideal_date,
n.actual_date,
abs(DATEDIFF(minute,n.ideal_date,n.actual_date)) as minutes
from table_date n

PostgreSQL: Column containing seconds to Hours Minutes Seconds Days INTERVAL SECONDSDIFF

I want to convert a column which contains seconds (i.e 11549404) into days, hours, minutes, seconds
SELECT (myCol || ' second')::interval, 'HH24 hrs MI "minutes" SS "seconds"') AS duration
FROM public.myTable
Which returns the following;
"3208 hrs 10 minutes 04 seconds"
Whats the way to display it as days, hours, minutes seconds
Because some days has 23hours and others 25hours the result is not easy task (it is not possible, because don't know absolute value). interval type is a structure of months, days and seconds. The values are not automatically moved between these fields because mounts has different number of days, days can has different number of seconds. But you can do some normalization - there is a function justify_interval that expects so days has 24 hours every time:
postgres=# select justify_interval('3208 hrs 10 minutes 04 seconds'::interval);
+-------------------------+
| justify_interval |
+-------------------------+
| 4 mons 13 days 16:10:04 |
+-------------------------+
(1 row)

Time range graph using Grafanas variables

We are using the graph compare time and we want to compare the amount of sessions for example between 14 days ago and 28 days ago and same wih 30 days ago and 60 days ago.
We currently wrote date BETWEEN $__timeFrom() AND $__timeTo() and it changes upon selecting the date ranges on the top right but we want the client to be able to change the date ranges and for this query to adjust to show -14 days and -30 days ago as well.
SELECT
$__timeGroup(date, '24h'),
sum(sessions) as sessions
FROM
ourchart
WHERE
date BETWEEN $__timeFrom() AND $__timeTo()
group by time
order by time
EDIT - I am able to make intervals of course but we are trying to compare this month to last month in the same graph....
Play with interval math. Example, which will move your timerange 30 days back:
date BETWEEN
timestamp $__timeFrom() - interval '30 days' AND
timestamp $__timeTo() - interval '30 days'

PostgreSQL interval subtraction

I've tried to subtract interval from timestamp, but I've got a wrong result in comparison to days via subtracting 2 dates.
E.g.:
select
(now::date - past::date) as days,
(now::date - past::date) / 365.25 as years,
justify_interval(now - past::date) as interval_test
from (
select '2020-09-17 00:00:01'::timestamp as now, '2010-09-17 00:00:01'::timestamp as past
) b;
gives results:
3653 days
10.0013 years
'10 years 1 mon 23 days' interval test
Could anyone help me to understand what is wrong with subtracting?
When I do it vice versa, it's ok:
select
(past::date + 3653)::date,
(past + interval '10 years')::date,
(past + 10*interval '1 year')::date,
(past + 10*12*interval '1 month')::date
from (
select '2020-09-17 00:00:01'::timestamp as now, '2010-09-17 00:00:01'::timestamp as past
) b;
all results give the same date '2020-09-17'
What I do wrong?
I am using PostgreSQL 10.5.
There is nothing wrong with subtracting. It is just that justify_interval doesn't do what you seem to expect. justify_interval uses 30 day months and 24 hour days. So 12 months becomes only 360 and 10 years only 3600 days. Leaving 53 days which is 1 (30 day) month and 23 days.
Edit
The justify_interval documentation on this page refers to justify_days and justify_hours which are directly above it which do mention the use of 30 days months and 24 hour days.
The justify functions do have to make these assumption because the interval type is a general length of time (it has no specific start and end). So the justify functions does not know over which specific months the interval was originally calculated.
The age function however does not take an interval it takes an end and a start so it actually knows which specific months and years are in that period.

How to calculate average weekly hours between 2 dates covering multiple weeks?

Postgresql 8.4.
I'm new to this concept so if people could teach me I'd appreciate it.
For Obamacare, anyone that works 30 hours per week or more must be offered the same healthcare as is offered to any other worker. We can't afford that so we have to limit work hours for temp and part-timers. This is affecting the whole country.
I need to calculate the hours worked (doesn't matter if overtime,
regular time, double time, etc) between two dates, say Jan 1, 2014,
and Nov 1, 2014 (Saturday) for each custom week (which beings on Sunday), not the week as defined by Postgresql (which begins on Monday).
Each of my custom work weeks begins on Sunday and ends on Saturday.
I don't know if I have to include weeks where
they did not work at all in the average, but let's assume I do. Zero hours that week would draw down the average.
Table name is 'employeetime', date field is 'employeetime.stopdate', hours worked per day is in the field 'employeetime.hours', employeeid field is 'employeetime.empid'.
I'd prefer to do this in one query per employee and I will execute the query once per employee as I loop through employees. If not I'm open to suggestions. But I'd like to understand the SQL presented in the answer.
Currently EXTRACT(week from '2014-01-01') calculates the start of the week as a Monday, so that doesn't work for me. Link here.
How would I do that without doing, say a separate query for each week, per person? We have 200 people to process.
Thank you.
I have set up a table to match your format:
select * from employeetime order by date;
id date hours
1 2014-11-06 10
1 2014-11-07 3
1 2014-11-08 5
1 2014-11-09 3
1 2014-11-10 5
You can get the week starting on Sunday by shifting. Note, here the 9th is a Sunday, so that is where we want the boundary.
select *, extract(week from date + '1 day'::interval) as week
from employeetime
order by week;
id date hours week
1 2014-11-07 3 45
1 2014-11-06 10 45
1 2014-11-08 5 45
1 2014-11-09 3 46
1 2014-11-10 5 46
And now the week shifts on Sunday rather than Monday. From here, the query to get hours by week/employee would be simple:
select id, sum(hours) as hours, extract(week from date + '1 day'::interval) as week
from employeetime
group by id, week
order by id, week;
id hours week
1 18 45
1 8 46