Finding the nth Particular Week in a Month – shell script


 
Thread Tools Search this Thread
Top Forums UNIX for Beginners Questions & Answers Answers to Frequently Asked Questions Finding the nth Particular Week in a Month – shell script
# 1  
Old 12-05-2012
Finding the nth Particular Week in a Month – shell script

I see lot of request posted in internet to find out the day of nth week in a Month.


example:
what is the date of 3rd Sunday in October
What is the date of 2nd Friday in June 2012
what is the date of 4th Saturday in January 2011..etc..


The below shell script is used to find out the days for the nth particular week in a month.
Try it out and shout if you find any issues… (Script is tested in bash shell. OS – linux(ubuntu))


Code:
#!/bin/bash
###################################
# Script Name : finday.sh                                               
# Author : Kamaraj Subramanian                                 
# Website : www.unix.com                              
# Bugs : this thread   
###################################
USAGE()
{
    echo "----------------------------------------------------------------"
    echo "USAGE :: findday YEAR MONTH DAY WEEK"
    echo "Example :"
    echo "findday 2012 10 SU 3"
    echo "The above will tell the date of 3rd sunday in October 2012"
    echo "Valid values for YEAR ( 1 to 9999 )"
    echo "Valid values for MONTH ( 1 to 12 )"
    echo "Valid values for DAY ( SU, MO, TU, WE, TH, FR, SA )"
    echo "Valid values for WEEK ( 1 to 5 )"
    echo "----------------------------------------------------------------"
    exit 1
}

YearCheck()
{
    echo "$1" | grep -v "^[0-9]*$" >/dev/null 2>&1 && echo "Please enter the number 1 to 9999" && USAGE
    if [[ ! "${1}" -le "10000" || "${1}" -eq "0" ]]
    then
        echo "Enter the correct Year [1-9999]"
        USAGE
    fi
    
}

MonthCheck()
{
    echo "$1" | grep -v "^[0-9]*$" >/dev/null 2>&1 && echo "Please enter the number 1 to 12" && USAGE
    if [[ ! "${1}" -le "12" || "${1}" -eq "0" ]]
    then
        echo "Enter the correct Month [1-12]"
        USAGE
    fi
}
DayCheck()
{
    echo "$1" | egrep -v "^SU$|^MO$|^TU$|^WE$|^TH$|^FR$|^SA$" >/dev/null 2>&1 && echo "Valid values for DAY ( SU, MO, TU, WE, TH, FR, SA )" && USAGE
    [ "$1" == "SU" ] && WNO=7 && PNO=1
    [ "$1" == "MO" ] && WNO=6 && PNO=2
    [ "$1" == "TU" ] && WNO=5 && PNO=3
    [ "$1" == "WE" ] && WNO=4 && PNO=4
    [ "$1" == "TH" ] && WNO=3 && PNO=5
    [ "$1" == "FR" ] && WNO=2 && PNO=6
    [ "$1" == "SA" ] && WNO=1 && PNO=7
    
}
WeekCheck()
{
    if [[ ! "${1}" -le "5" || "${1}" -eq "0" ]]
    then
        echo "Enter the correct WEEK [1-5]"
        USAGE
    fi
}

if [ "$#" -ne "4" ]
then
    USAGE
else
    YearCheck $1
    MonthCheck $2
    DayCheck $3
    WeekCheck $4
    echo "---------------"
    echo "Given Inputs"
    echo "---------------"
    echo "YEAR  :: $1"
    echo "MONTH :: $2"
    echo "DAY   :: $3"
    echo "WEEK  :: $4" 
    echo "---------------"
    cal $2 $1 | awk -v n="$4" -v WNO="$WNO" -v PNO="$PNO" '
    {
    if(NR==3)
    {
        if(NF==WNO)
        {
            a=2;
        }
        else
        {
            a=3;
        }    
    }
    if(a && NR==(a+n))
    {
        if(length($PNO)>0)
        {
            printf("Output Date : %s\n",$PNO);
        }
        else
        {
            printf("Requested week date is not available for the given month year combination\n");
        }
        exit;
    }
    }'
fi

output


Code:
$ ./findday.sh 2012 12 SA 5
---------------
Given Inputs
---------------
YEAR  :: 2012
MONTH :: 12
DAY   :: SA
WEEK  :: 5
---------------
Output Date : 29
 
$ cal 12 2012
   December 2012      
Su Mo Tu We Th Fr Sa  
                   1  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
30 31                 
 
$ ./findday.sh 2012 12 FR 5
---------------
Given Inputs
---------------
YEAR  :: 2012
MONTH :: 12
DAY   :: FR
WEEK  :: 5
---------------
Requested week date is not available for the given month year combination

These 3 Users Gave Thanks to itkamaraj For This Post:
# 2  
Old 12-05-2012
It is kind and generous of you to share your script with the rest of us. Thank you very much.

I have a few observations which may or may not interest you. If they do not, then nevermind me.

Quote:
Originally Posted by itkamaraj
Code:
$ ./findday.sh 2012 12 SA 5
---------------
Given Inputs
---------------
YEAR  :: 2012
MONTH :: 12
DAY   :: SA
WEEK  :: 5
---------------
Output Date : 29
 
$ cal 12 2012
   December 2012      
Su Mo Tu We Th Fr Sa  
                   1  
 2  3  4  5  6  7  8  
 9 10 11 12 13 14 15  
16 17 18 19 20 21 22  
23 24 25 26 27 28 29  
30 31                 
 
$ ./findday.sh 2012 12 FR 5
---------------
Given Inputs
---------------
YEAR  :: 2012
MONTH :: 12
DAY   :: FR
WEEK  :: 5
---------------
Requested week date is not available for the given month year combination

Your script may work fine for interactive use, where a human invokes it at the command line and then reads the output, but it's not well designed for non-interactive use, such as feeding a pipeline or assigning a value to a variable.

To me, the interactive case isn't compelling; your script doesn't really provide much benefit as opposed to just using cal. Reading cal's output would give the same information with about the same effort.

However, where cal's output isn't very easy to work with non-interactively, your script's output could be a simple pleasure.

I would suggest, in keeping with UNIX's tradition of not saying much when there is little to say, that your script's only output be a single number, 0 through 31, followed by a newline.

To facilitate the case where someone only wants to know whether there's a 5th instance of a day in a month, the exit status could be set to non-zero.

Also, for non-interactive use especially, the script should print error, diagnostic, and usage messages to standard error, not standard output, so that they go to the correct place. It would cause confusion if usage information where sent into a pipe expecting script output. In its present form, your code will not play nice if standard error and standard output have been redirected to different places (which is the default behavior of a pipeline).

If you are attached to the currently verbose output, you could make it an option, such as -v. But, even in a verbose mode, it would be a good idea to kill the header info; it doesn't add any value. Also, a simple tab, instead of the whitespace and colons currently delimiting the two fields of each line, complements nicely the splitting behavior of cut, awk, read, and friends.

To summarize my suggestions with a mock terminal session:
Code:
$ ./findday.sh 2012 12 SA 5
29
$ echo $?
0
$ ./findday.sh 2012 12 FR 5
0
$ echo $?
1
$ ./findday.sh
Usage message here ...
$ echo $?
2

Now we can do things like:
Code:
# Run commands only if January 2013 begins with a Wednesday or has 5 Saturdays
if [ $(findday 2013 01 WE 1) -eq 1 ] || findday 2013 01 SA 5 >/dev/null; then
    cmd1
    cmd2
    ...
    cmdN
fi

Whether you are interested in my critique or not, thanks again for your contribution. It's appreciated.

Regards,
Alister
This User Gave Thanks to alister For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Get 1st date of month, week , quarter

Hi , I need to trigger few jobs based on the system date ( in case user is not passing any date to the script. In case passing then need to take the user date). Here is the requirement 1. Everyday call daily script 2. On 1st day of week call weekly script 3. On 1st day of month call... (4 Replies)
Discussion started by: Anupam_Halder
4 Replies

2. Shell Programming and Scripting

Run shell script alternate week per month

Hi All, Requirement :- I have shell script in kern shell ,have to run alternate week per month example-today's date is 27 Mar 2013 and my script will run today then for the next time when it will run it should check 1st what was the last run date(27 Mar 2013) if it is matched 15days from... (2 Replies)
Discussion started by: krupasindhu18
2 Replies

3. Shell Programming and Scripting

Finding Nth Column

Please help me how can I display every nth field present in a "|" delimited file. Ex: If a have a file with data as a|b|c|d|e|f|g|h|k|l|m|n I want to display every 3rd feild which means the output should be c f k n Please help me. (1 Reply)
Discussion started by: ngkumar
1 Replies

4. Shell Programming and Scripting

Displaying time left to end of day, week, month?

Hello, basically I'm looking after a way of showing how many time is left to the end the day, week, month... I can't seem to figure this out, so could one of you skilled guys tell me how should this be approached? Examples: Time left: Day: 12h 12m 11s Week: 4d 12h 12m 11s Month:... (4 Replies)
Discussion started by: TehOne
4 Replies

5. Shell Programming and Scripting

Day of the week or Month in a foreign language

Hey guys, i'm a very new shell script user. I've been looking everywhere for a proper script to display the day of the week or the month, accurately, in a foreign language of my choosing. Something where i can just type in the appropriate word in a foreign language in the script and get the... (2 Replies)
Discussion started by: ibizagreg
2 Replies

6. UNIX for Dummies Questions & Answers

finding the nth match

I have a file that has information for a person....each person gets 3 or more lines to describe them. I was hoping to match person 1, then person 2.....BUT I do not know how to tell grep I only want the first (2nd, 3rd or nth) match. The alternative is doing line by line logic, which is fine... (8 Replies)
Discussion started by: countryStyle
8 Replies

7. Shell Programming and Scripting

Execute a script on 4 week of the month

I need help to write a script and it will execute on Saturday of the last week of every month. For example : 09/30/2006 is the last Saturday on Sept. 2006 08/26/2006 is the last Saturday on Aug. 2006 07/29/2006 is the last Saturday on July. 2006 etc.. ... (1 Reply)
Discussion started by: tbdo88
1 Replies

8. UNIX for Dummies Questions & Answers

setting up cron job for month end week report

Hi all, Needs your help in scheduling a cron job for the below mentioned requirement. Just let me know if anybody has a similar job running as mentioned below: Month end reports - Report of all items created in a parent table that were created during the week. Presently this report runs... (3 Replies)
Discussion started by: Bhups
3 Replies

9. Shell Programming and Scripting

Getting week in month.???

Hi All, I have a tricky problem. I need to write a shell script (bash) which identifies which week off the month it is. I need to create a partition each week. So for the first week (where first of the week is Monday) of March i want to create partition_march_01 and for the second partition... (1 Reply)
Discussion started by: Zak
1 Replies
Login or Register to Ask a Question