Count occasions when my birthday falls on a weekend - oracle

I want to calculate how many times my birthday is on a weekend.
declare
v_count number;
v_birthday date := '22-07-1993';
v_sysdate date := sysdate;
begin
--1) first i have to know all the dates when it was my birthday till sysdate.
--2) then i have to convert it to a char(?) and look if its in the weekend (saturday or sunday)
--3) if yes, count have to be increased by one, if not, go to the next birthday till sysdate.
--4) show count in dbms.output_put_line(v_count);
-- ("for i_counter in 1..10 loop" and "while i_counter <=10 loop"
end;
I think I have to use a LOOP, but I only know LOOPs with numbers, not dates.

This code will count the number of days that JULY 22 will occur on a weekend (SATURDAY or SUNDAY) between 1993 and 2014 inclusive:
set serveroutput on size 100000
declare
V_DATE DATE;
I NUMBER;
WEEKEND_COUNT NUMBER;
begin
WEEKEND_COUNT := 0;
FOR I IN 1993 .. 2014
LOOP
V_DATE := TO_DATE('07/22/' || TO_CHAR(I), 'MM/DD/YYYY');
DBMS_OUTPUT.PUT_LINE(
'DATE: ' || V_DATE || ' ' ||
'DAY_OF_WEEK: ' || TO_CHAR(V_DATE, 'DY'));
IF TO_CHAR(V_DATE, 'DY') = 'SAT' OR
TO_CHAR(V_DATE, 'DY') = 'SUN' THEN
WEEKEND_COUNT := WEEKEND_COUNT +1;
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE ('NUMBER OF BIRTHDAYS ON WEEKENDS: ' ||
WEEKEND_COUNT);
end;
The output is:
DATE: 22-JUL-93 DAY_OF_WEEK: THU
DATE: 22-JUL-94 DAY_OF_WEEK: FRI
DATE: 22-JUL-95 DAY_OF_WEEK: SAT
DATE: 22-JUL-96 DAY_OF_WEEK: MON
DATE: 22-JUL-97 DAY_OF_WEEK: TUE
DATE: 22-JUL-98 DAY_OF_WEEK: WED
DATE: 22-JUL-99 DAY_OF_WEEK: THU
DATE: 22-JUL-00 DAY_OF_WEEK: SAT
DATE: 22-JUL-01 DAY_OF_WEEK: SUN
DATE: 22-JUL-02 DAY_OF_WEEK: MON
DATE: 22-JUL-03 DAY_OF_WEEK: TUE
DATE: 22-JUL-04 DAY_OF_WEEK: THU
DATE: 22-JUL-05 DAY_OF_WEEK: FRI
DATE: 22-JUL-06 DAY_OF_WEEK: SAT
DATE: 22-JUL-07 DAY_OF_WEEK: SUN
DATE: 22-JUL-08 DAY_OF_WEEK: TUE
DATE: 22-JUL-09 DAY_OF_WEEK: WED
DATE: 22-JUL-10 DAY_OF_WEEK: THU
DATE: 22-JUL-11 DAY_OF_WEEK: FRI
DATE: 22-JUL-12 DAY_OF_WEEK: SUN
DATE: 22-JUL-13 DAY_OF_WEEK: MON
DATE: 22-JUL-14 DAY_OF_WEEK: TUE
NUMBER OF BIRTHDAYS ON WEEKENDS: 6

Related

exp_date=Thu Sep 9 14:06:38 UTC 2021 reduce 30 days from exp_date in shell script

exp_date=Thu Sep 9 14:06:38 UTC 2021 reduce 30 days from exp_date in shell script
I know from current date I can use this date --date "30 days ago" But when I try it from a date variable to do the same its not working
Use date to get your date in epoch seconds.
Subtract 30 days of seconds.
Convert the epoch seconds to ... whatever you need:
root#pi:~# date
Sun 19 Sep 2021 04:07:01 PM CDT
root#pi:~# date -d #$(( $(date -d 'Wed Nov 13 14:06:38 UTC 1954' +%s) - 30*86400 ))
Thu 14 Oct 1954 08:06:38 AM CST

Spring boot cron expression, every 2 month

I wanted to construct a spring cron expression that executes At 23:00:00pm, on first Sunday, every 2 months starting in January, so far I have this
0 0 23 ? 1/2 SUN but this one executes At 23:00:00pm, every Sunday, every 2 months starting in January. how can I make it execute only the first Sunday every two months?
0 0 23 ? 1/2 SUN next excution dates are as follows
Sun Mar 07 23:00:00 UTC 2021
Sun Mar 14 23:00:00 UTC 2021
Sun Mar 21 23:00:00 UTC 2021
Sun Mar 28 23:00:00 UTC 2021
Sun May 02 23:00:00 UTC 2021
Sun May 09 23:00:00 UTC 2021
Sun May 16 23:00:00 UTC 2021
Sun May 23 23:00:00 UTC 2021
Sun May 30 23:00:00 UTC 2021
Sun Jul 04 23:00:00 UTC 2021
but what I wanted was
Sun Mar 07 23:00:00 UTC 2021
Sun May 02 23:00:00 UTC 2021
Sun Jul 04 23:00:00 UTC 2021
how can I improve my expression to get the above result?
0 0 23 1-7 1/2 SUN
The only part you are missing, is day number in the range 1-7.
Code to verify the schedule:
var sundays = CronExpression.parse("0 0 23 1-7 1/2 SUN");
var nextDate = LocalDateTime.now();
var dateFormatter = DateTimeFormatter.ofPattern("EEE, MMM d, yyyy 'at' hh:mm:ss a");
for (var i = 0; i < 10; i++) {
nextDate = sundays.next(nextDate);
System.out.println(nextDate.format(dateFormatter));
}
Will run at:
Sun, Mar 7, 2021 at 11:00:00 pm
Sun, May 2, 2021 at 11:00:00 pm
Sun, Jul 4, 2021 at 11:00:00 pm
Sun, Sep 5, 2021 at 11:00:00 pm
Sun, Nov 7, 2021 at 11:00:00 pm
...

Looping with an specific step in a long datetime string in bash

I have a list of files with the substring YYYYMMDDHH in them (example: 2016112200 means 2016 November 22th at 00 hours). These files are: temp_2016102200.data, temp_2016102212.data, temp_2016102300.data, temp_2016102312.data, ..., temp_20170301.data. And I also have other family of files substituting temp by wind.
For each string YYYYMMDDHH I want to create a tar with the temp and its correspondent wind file. I don't want this process to stop if one or both files are missing.
My idea was to loop from 12 hours to 12 hours, but I am having some problems because to specify the date I did: b=$(date -d '2016111400' +'%Y%m%d%H') but bash informs me that that is not a valid date...
Thanks.
It's not bash telling you the date format is wrong: date is telling you. Not everything you type is a bash command.
As Kamil comments, you have to split it up so that date can parse it. The YYYY-mm-dd HH:MM:SS format is parsable. Using bash parameter expansion to extract the relevant substrings:
$ d=2016111400
$ date -d "${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00"
Mon Nov 14 00:00:00 EST 2016
Now, when you want to add 12 hours, you have to be careful to do it in the right place in the datetime string: if you add a + character after the time, it will be parsed as a timezone offset, so put the relative part either first or between the date and the time.
$ date -d "+12 hours ${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00"
Mon Nov 14 12:00:00 EST 2016
As a loop, you could do:
d=2016111400
for ((i=1; i<=10; i++)); do
# print this datetime
date -d "${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00"
# add 12 hours
d=$( date -d "+12 hours ${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00" "+%Y%m%d%H" )
done
outputs:
Mon Nov 14 00:00:00 EST 2016
Mon Nov 14 12:00:00 EST 2016
Tue Nov 15 00:00:00 EST 2016
Tue Nov 15 12:00:00 EST 2016
Wed Nov 16 00:00:00 EST 2016
Wed Nov 16 12:00:00 EST 2016
Thu Nov 17 00:00:00 EST 2016
Thu Nov 17 12:00:00 EST 2016
Fri Nov 18 00:00:00 EST 2016
Fri Nov 18 12:00:00 EST 2016
OK, a "nicer" way to loop
start=2019043000
end=2019050300
plus12hours() {
local d=$1
date -d "+12 hours ${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00" "+%Y%m%d%H"
}
for (( d = start; d <= end; d = $(plus12hours "$d") )); do
printf "%d\t%s\n" "$d" "$(date -d "${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:00:00")"
done
2019043000 Tue Apr 30 00:00:00 EDT 2019
2019043012 Tue Apr 30 12:00:00 EDT 2019
2019050100 Wed May 1 00:00:00 EDT 2019
2019050112 Wed May 1 12:00:00 EDT 2019
2019050200 Thu May 2 00:00:00 EDT 2019
2019050212 Thu May 2 12:00:00 EDT 2019
2019050300 Fri May 3 00:00:00 EDT 2019

How to fetch 5th and 6th day of every month in Unix?

Is it possible to fetch 5th and/or 6th day of every month in Unix?
I've tried this but it does not give me the desired output:
echo $((($(date +%-d)-1)/5))
Use this:
for month in {1..12}; do date -d "$month/5/2017" +"%c - is a %A"; done
Output:
Thu 05 Jan 2017 12:00:00 AM CET - is a Thursday
Sun 05 Feb 2017 12:00:00 AM CET - is a Sunday
Sun 05 Mar 2017 12:00:00 AM CET - is a Sunday
Wed 05 Apr 2017 12:00:00 AM CEST - is a Wednesday
Fri 05 May 2017 12:00:00 AM CEST - is a Friday
Mon 05 Jun 2017 12:00:00 AM CEST - is a Monday
Wed 05 Jul 2017 12:00:00 AM CEST - is a Wednesday
Sat 05 Aug 2017 12:00:00 AM CEST - is a Saturday
Tue 05 Sep 2017 12:00:00 AM CEST - is a Tuesday
Thu 05 Oct 2017 12:00:00 AM CEST - is a Thursday
Sun 05 Nov 2017 12:00:00 AM CET - is a Sunday
Tue 05 Dec 2017 12:00:00 AM CET - is a Tuesday
For the 6th of the month, it's done in a similar way.
I am not sure if this is what you are looking for: i am assuming you want to get the 5th(or 6th) day of a month sitting on any day. If so, you can make use of the current date and get the 5th day of current month like below:
dd=`date '+%d'`
if(( $dd > 5 )); then
(( diff = dd - 5 ))
myDate=`date -d "-$diff days"`
else
(( diff = 5 - dd ))
myDate=`date -d "+$diff days"`
fi
echo $myDate
For 6th day you can do similarly. Above code should work on Linux distro.

DateTime parsing of weeks for '30 Dec 2013' is incorrect

DateTime#parse on 'Mon, 30 Dec 2013 00:00:00 UTC +00:00' is wrong for the week. I chose ISO 8601 week-based year and week number %V (week number 01..53 of the week-based year).
With format "%V-%y":
DateTime.parse('Mon, 30 Dec 2013 00:00:00 UTC +00:00').strftime "%V-%y"
#⇒ "01-13"
DateTime.parse('Mon, 30 Dec 2013 00:00:00 UTC +00:00').strftime "%W-%y"
#⇒ "52-13"
Date.strptime('01-13', '%V-%y')
#⇒ Tue, 01 Jan 2013
Date.strptime('52-13', '%V-%y')
#⇒ Tue, 01 Jan 2013
Mon, 30 Dec 2013 00:00:00 UTC +00:00 is not "01-13".
But if I use "%W" format, the result is correct ("52-13").
What is it? Or did I make some mistakes?
With week-based week number (%V) one should use week-based year (%g):
DateTime.parse('Mon, 30 Dec 2013 00:00:00 UTC +00:00').strftime "%V-%g"
#⇒ "01-14"
The cday, cweek and cyear are the methods based on the commercial dates.
commercial: Creates a date object denoting the given week date.
So, the last days of an year can be the same week to the new year's starting days. For example 2013 december last dates and 2014 Jan starting days are of the same week, so the week number of the date 'Mon, 30 Dec 2013 00:00:00 UTC +00:00' comes to the new week of next year after all the weeks of the year are completed.
So,
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.cweek ==> 1
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.cwday ==>1 (1st week day of week 1 2014(but date is still of 2013)
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.cwyear ==> 2014
Those are commercial dates, Now check,
"Mon, 30 Dec 2013 00:00:00 UTC +00:00".to_date.year ==> 2013
This is Normal year.
This has a perfect example

Resources