Script to find n.of weekdays and n.of weekends in a given date


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Script to find n.of weekdays and n.of weekends in a given date
# 8  
Old 09-11-2016
The sample dates that were provided in post #1 seem to be in the format YYYY-MM-DD (although from the examples supplied and the lack of any specification, they could also be in the format YYYY-DD-MM). RavinderSingh13's code seems to be treating the dates as though they were in the format DD-MM-YY. (Note that the outputs from cal shown in post #4 in this thread are from the years 0015, 0014, and 0022.) The code suggested in post #6 works correctly for inputs in the format DD-MM-YYYY, but not for inputs in the format YYYY-MM-DD. Note also that it invokes cal twice and awk four times for each date processed.

You might want to consider the following script which processes inputs in the format YYYY-MM-DD and only invokes cal once and awk once for each date processed:
Code:
#!/bin/ksh
IAm=${0##*/}
if [ $# -eq 0 ]
then	printf 'Usage: %s YYYY-MM-DD...\n' "$IAm" >&2
	exit 1
fi
# Process each operand given...
while [ $# -gt 0 ]
do	# Grab year from start of the operand.
	year=${1%%-*}
	# Throw away the day from the end of the operand.
	month=${1%-*}
	# Throw away the year (leaving the month) from the operand.
	month=${month#*-}
	# Read the desired variable values from the following awk script...
	read var120 var28 <<-EOF
		$(cal $month $year | awk '
			NR > 2 && NF {
				# We have skipped over the leading header lines
				# and any empty lines, so what we have left are
				# the days in a given week.  If we have seven
				# days in this week, we have 2 weekend days and
				# 5 weekdays, otherwise we have one weekend day
				# and NF - 1 weekdays.
				weekenddays += 1 + (NF == 7)
				weekdays += NF - 1 - (NF == 7)
			}
			END {	# Print the results...
				print weekdays, weekenddays
			}
		')
	EOF
	printf '%s %d week-days and %d weekend-days in %s-%s\n' \
	    'Do whatever you want with' "$var120" "$var28" "$year" "$month"
	shift
done

If you save this script in a file named tester and make it executable, invoking it with:
Code:
./tester 2016-09-10 2016-02-12 2016-08-05 2015-02-12 2016-01-31

it produces the output:
Code:
Do whatever you want with 22 week-days and 8 weekend-days in 2016-09
Do whatever you want with 21 week-days and 8 weekend-days in 2016-02
Do whatever you want with 23 week-days and 8 weekend-days in 2016-08
Do whatever you want with 20 week-days and 8 weekend-days in 2015-02
Do whatever you want with 21 week-days and 10 weekend-days in 2016-01

This was written and tested using the Korn shell on OS X, but will work with any shell that performs basic shell parameter expansions required by the POSIX standards. As always, if you want to try this on a Solaris/SunOS system, change awk to /usr/xpg4/bin/awk or nawk.
This User Gave Thanks to Don Cragun For This Post:
# 9  
Old 09-12-2016
Thank you Don for nice code. I made little modifications into my previous code and now we need not to run caland awk1 time.

Hello ROCK_PLSQL,

You could give a try to following code too and as Don mentioned above too, you could save following values(I given in comments which variable value is which) to further as per your use too.
Code:
cat script_cal.ksh 
MONTH=`echo $1 | cut -d- -f2`
YEAR=`echo $1 | cut -d- -f3`
VAL=`cal $MONTH $YEAR | awk 'NR>2 && NF{
                    if($0 ~ /^[[:space:]]/){
                                A[$NF]++;
                                   };
                    if(($0 !~ /^[[:space:]]/) && NF<7){
                                        B[$1]++;
                                          };
                    if(NF==7){
                            B[$1]++;
                            A[$NF]++
                         };
                    Q=$NF
                      } 
                END       {
                    print Q-length(A)-length(B)"-"length(A)+length(B);
                  }
                       '`
echo ${VAL##*-}  ##This is value of weekends in a month var28
echo ${VAL%%-*}  ##This is value of weekdays in a month var120

NOTE: Date should be passed into DD-MM-YYYY format.

Thanks,
R. Singh

Last edited by RavinderSingh13; 09-12-2016 at 06:16 AM.. Reason: Removed NOTE's format of date as per Don's suggestion. Thanks to Don for same.
# 10  
Old 09-12-2016
Code:
#!/bin/bash

GIVEN_DATE=${1}
YEAR=$(echo ${GIVEN_DATE} | cut -d- -f1)
MONTH=$(echo ${GIVEN_DATE} | cut -d- -f2)
cal ${MONTH} ${YEAR} | awk 'NR>2&&NF!=0{if(NF==7){w+=2;}else{w+=1;}E=$NF}END{print w,E-w}' | while read WEEKEND WEEKDAY
do
	echo "Week Day : ${WEEKDAY}"
	echo "Week End : ${WEEKEND}"
done

# 11  
Old 09-12-2016
Hi Ravinder,
Note that cal doesn't treat a 2-digit year operand as a year in the late 20th or early 21st century like the touch -t option-argument does; cal treats it as a literal 2 digit year in the 1st century. For example, look at the difference between February 2004 and February 04:
Code:
$ cal 2 2004
   February 2004
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

$ cal 2 04
     February 4
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

$

(Note: 8 weekend days in year 2004 and 9 weekends days in year 4.) So, if you're going to use cal, the entire year has to be supplied; not just the last two digits.

Note that using cut instead of awk to split month, day, and year out of the given operand still involves the very expensive fork and exec operations that could be done MUCH quicker just using parameter expansions built into the shell.
This User Gave Thanks to Don Cragun For This Post:
# 12  
Old 09-12-2016
Do you have the ncal command available? Try
Code:
set 2016-09-10
TMP=${1#*-}; ncal ${TMP%-*} ${1%%-*} | awk 'NR>1 && NR<7 {WD+=NF-1} NR>=7 {WE+=NF-1} END {print WD, WE}'
22 8

EDIT: Or, just shell:
Code:
TMP=${1#*-}; ncal ${TMP%-*} ${1%%-*} | { read; while read A; do set $A; case $1 in S?) (( WE+=$#-1));; *) (( WD+=$#-1)); esac;  done; echo $WD, $WE; }
22, 8


Last edited by RudiC; 09-12-2016 at 05:17 AM..
# 13  
Old 09-12-2016
Hi.

I've mentioned the dateutils suite of date utilities before. The reason that I like the codes is that they make sure the dates exist, they diagnose bad forms, etc.

Applied here to the problem, we first get a year-month sequence (dconv), then add a month (dadd), then generate a sequence of the days in the month (dseq), omitting the first day of the next month.

Then it's a matter of counting weekdays and weekENDS, a short grep-wc pipeline:
Code:
#!/usr/bin/env bash

# @(#) s1       Demonstrate count weekdays, weekENDs in a given month.

# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C dateutils.dconv dateutils.dadd dateutils.dseq

pe
if [ $# -gt 0 ]
then
  set -- 2016-9.11
else
  set -- 2016-09-10 2016-02-12 2016-08-05 2012-2-15 2012-10-14 2012-01-22 2017-02-29 2016-02-29
fi

for YMD
do
  # YearMonthNow, YearMonthFuture.
  dateutils.dconv -f "%Y-%m" "$YMD" > /dev/null
  ES=$?
  db " Exit status of dconv is :$ES: for date $YMD"
  if [ $ES -ne 0 ]
  then
        pe
    em " Skipping input, date has bad form or is impossible: \"$YMD\""
        continue
  else
        YMN=$( dateutils.dconv -f "%Y-%m" "$YMD" )-01
  fi
  db " YMN is $YMN"
  YMF=$( dateutils.dadd -f "%Y-%m" "$YMD" +1m )-01
  db " YMF is $YMF"
  ymd=$( dateutils.dseq -i "%Y-%m-%d" -f "%F %a" $YMN $YMF | sed '$d' )
  db " ymd = $ymd"
  
  weekdays=$( echo "$ymd" |
    grep -E 'Mon|Tue|Wed|Thu|Fri' |
  wc -l)
  weekends=$( echo "$ymd" |
    grep -E 'Sat|Sun' |
  wc -l )
  
  pl " For date $YMD:"
  pe " Weekdays = $weekdays"
  pe " WeekENDS = $weekends"
done

exit 0

producing:
Code:
$ ./s1

Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution        : Debian 8.4 (jessie) 
bash GNU bash 4.3.30
dateutils.dconv dconv 0.3.1
dateutils.dadd dadd 0.3.1
dateutils.dseq dseq 0.3.1


-----
 For date 2016-09-10:
 Weekdays = 22
 WeekENDS = 8

-----
 For date 2016-02-12:
 Weekdays = 21
 WeekENDS = 8

-----
 For date 2016-08-05:
 Weekdays = 23
 WeekENDS = 8

-----
 For date 2012-2-15:
 Weekdays = 21
 WeekENDS = 8

-----
 For date 2012-10-14:
 Weekdays = 23
 WeekENDS = 8

-----
 For date 2012-01-22:
 Weekdays = 22
 WeekENDS = 9

 Skipping input, date has bad form or is impossible: "2017-02-29"

-----
 For date 2016-02-29:
 Weekdays = 21
 WeekENDS = 8

Included is a date in February that would not exist next year (2017), but exists this year (2016 being a leap year).

Best wishes ... cheers, drl
# 14  
Old 09-12-2016
Code:
#input date as 20160912
M=$1
Start=`expr  $M - $M % 100`
Start=`expr $Start + 1`
End=`expr $Start + 100`
echo $Start $End
sj=`date --date="$Start" +%j`
ej=`date --date="$End" +%j`
lj=`expr  $ej - $sj`
echo $ej $sj $lj
i=1
weekend=0
weekday=0
while [ $i -le $lj ]
do
test_day=`date --date="$Start" +%u`
if [ $? -eq 0 ]
then
  echo $Start $test_day
  if [ $test_day -gt 5 ]
  then
   weekend=`expr $weekend + 1`
  else
   weekday=`expr $weekday + 1`
  fi
fi
Start=`expr $Start + 1`
i=`expr $i + 1`
done 
echo weekdays $weekday
echo weekends $weekend

Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Script to find a date variable and increment it

Hi, I have parameter file wo_location.prm which has a date variable $last_upd_date= 02032016. I need to write a unix shell script to find that variable and increment it by 1 day. The path to the file is root/dir_lc/shared/param/wo_location.prm and the variable is $last_upd_date. Any... (2 Replies)
Discussion started by: isenhiem
2 Replies

2. Shell Programming and Scripting

How to find the date of previous day in shell script?

Hi Experts, i am using the below code get the date of previous day. #!/usr/bin/ksh datestamp=`date '+%Y%m%d'` yest=$((datestamp -1)) echo $yest When i execute the code i am getting output as: 20130715 What i am trying here is, based on the date passed i am fetching previus day's... (0 Replies)
Discussion started by: learner24
0 Replies

3. Shell Programming and Scripting

How to find the router reboot date using script?

Hai Iam having router output in a text file.from this data how to find out the router reboot date and time using script bgl-ras-bng-bge-09>show version | grep Time Router Up Time - 61 days, 21 hours 31 minutes 49 secs bgl-ras-bng-bge-09>show clock Thu Feb 14 10:16:14 2013 IST output... (6 Replies)
Discussion started by: surender reddy
6 Replies

4. Shell Programming and Scripting

bash script to find date based on search string for continuesly updating file

Hi All, I am very new to UNIX and I have tried this for a longtime now and unable to crack it.... There is a file that is continuously updating. I need to search for the string and find the date @ which it updated every day..... eg: String is "work started" The log entry is as below: ... (1 Reply)
Discussion started by: Nithz
1 Replies

5. Shell Programming and Scripting

How to script to find the newer date in a text file?

Hi, I have a text file, foo.txt, it looks something like below. In the file there is a line that gives the date in the form of: Mon Jun 15 11:09:31 2008. I need to find which date is the newest and then store certain details of that list data to another file. So, in this sample text file, I... (6 Replies)
Discussion started by: boolean2222
6 Replies

6. What is on Your Mind?

What do you do during weekends ? :)

Its been a while since we had any fun polls or interesting topics in this forum. So, here I start a thread rather calling it as a question - " What do you do during weekends ? :) " For many, on hearing the term - weekends should excite them :b: for ( few ) some - uhhh .. its just another day... (11 Replies)
Discussion started by: matrixmadhan
11 Replies

7. UNIX and Linux Applications

Code to find weekends in Sybase.

Hi All, I need a help here, actually i want SQl code which will determine all Saturdays and Sunday in given year (say 2009) and display it's dates. E.g :- 3 ---> Saturday 4 --> Sunday (for 2009) and so on. Thanks in Advance for help. Regards, Arvind. (0 Replies)
Discussion started by: arvindcgi
0 Replies

8. Shell Programming and Scripting

shell script to find latest date and time of the files

Hi everyone, Please help:) I have a list of 1000 different files which comes daily to the directory.Some of the files are not coming to the directory now. I need to write a shell script to find the latest date and time of the files they came to the directory. The files should be unique.... (1 Reply)
Discussion started by: karthicss
1 Replies

9. UNIX for Dummies Questions & Answers

shell script to find files by date and size

Hi, I have a directory PRIVATE in which I have several directories and each of these have several files. Therefore, I need to find those files by size and date to back up those files in another directory. I don't know how to implement this shell script using ''find''. appreciate any... (1 Reply)
Discussion started by: dadadc
1 Replies

10. Shell Programming and Scripting

Script to find files on a given input date

Hello gurus, I need to write a script to find out all the file that got changed on a specific folder since a given input date (Date to be given as Input) Thanx (1 Reply)
Discussion started by: ar.karan
1 Replies
Login or Register to Ask a Question