Set next/previous weekday - bash

With following code I can roll day in Linux back and forth.
date -s 'tomorrow'
date -s 'yesterday'
I would like to do the same but skip weekends.

The following gives you next working day (for bash):
if [[ $( date +%u ) -eq 5 ]] ; then date --date="next Monday" ; else date --date="next day" ; fi

This script sets the day to the next weekday. Before forewarned that these scripts strip out the time of day when jumping over the weekend. Also, they are not portable to limited shells like busybox.
week_day=$(date +%w) #get the week day as a number from 0
if [[ $week_day == 5 || $week_day == 6 ]] #check to see if it is Fri or Sat
then date -s 'next monday' #if it is Fri or Sat, the set day to next monday
else date -s tomorrow #it is a different day of the week, go to the next day
fi
The last week day
week_day=$(date +%w) #get the week day as a number from 0 to 6 starting with 0 as Sunday
if [[ $week_day == 0 || $week_day == 1 ]] #check to see if it is Sun or Mon
then date -s 'last friday' #if it is Sun or Mon, the set day to last friday
else date -s yesterday #it is a different day of the week, go to yesterday
fi

if [[ $( date +%u ) = 5 ]] ; then date --set="+3 days" ; else date --set="+1 days" ; fi
if [[ $( date +%u ) = 1 ]] ; then date --set="-3 days" ; else date --set="-1 days" ; fi

Related

check if shell argument is last day of month

i want to check if the passed argument in command line is the last day of month like below:
./check_date.sh 20210731
if 20210731 is the last day of month echo "last day of month"
else echo "no the last day of month"
mydate="$1"
#i found this code in stackoverflow thread but do not now if can take my argument to check weather is the last day or month or not
if [[ $(date -d "+1 day" +%m) != $(date +%m) ]]
then
echo "Today is the last day of the month"
else
echo "Today is NOT the last day of the month"
fi
thank you
Just check if 1 day added to your date $1, represented as day of month +%d, evaluates to 01:
if [[ $(date -d "$1 + 1 day" +%d) == 01 ]]
then echo "$1 is the last day of month"
else echo "$1 is NOT the last day of month"
fi

bash automate the user input <enter> in the loop

#!/bin/sh
dom=$(date '+%d') # 01-31, day of month
year=$(date '+%Y') # four-digit year
month=$(date '+%m') # two-digit month
nworkdays=0
for d in $( seq 1 $dom)
do
today=$(date -d "$year-$month-$d" '+%x') # locale's date representation (e.g. 12/31/99)
dow=$(date -d "$year-$month-$d" '+%u') # day of week: 1-7 with 1=Monday, 7=Sunday
if [ "$dow" -le 5 ] && grep -vq "$today"
then
workday=Yes
nworkdays=$((nworkdays+1))
else
workday=
fi
done
[ "$workday" ] && [ "$nworkdays" -eq 6 ] && echo "$nworkdays $today $workday"
~
I wanted to execute the script but the script goes inside the loop and asks for user input.
Expected result
on execution display workday
Best Regards,
Shalini
As mentioned by #urbanespacemen kindly remove the grep command
#!/bin/sh
dom=$(date '+%d') # 01-31, day of month
year=$(date '+%Y') # four-digit year
month=$(date '+%m') # two-digit month
nworkdays=0
for d in $( seq 1 $dom)
do
today=$(date -d "$year-$month-$d" '+%x') # locale's date representation (e.g. 12/31/99)
dow=$(date -d "$year-$month-$d" '+%u') # day of week: 1-7 with 1=Monday, 7=Sunday
if [ "$dow" -le 5 ]
then
workday=Yes
nworkdays=$((nworkdays+1))
else
workday=
fi
done
[ "$workday" ] && [ "$nworkdays" -eq 6 ] && echo "$nworkdays $today $workday"
Now should work

How to list date of every monday and thrusdays in shell scripting?

If I give month and year as input the output should be dates of mondays and thrusdays of that month.
eg: If input is
year = 2013
month = 02
output should be
2013-02-04
2013-02-07
2013-02-11
2013-02-14
2013-02-18
2013-02-21
2013-02-25
2013-02-28
how to use date function for this in shell scripting?
This method requires only 2 call to date, the rest is just arithmetic
year=2013
month=2
last=$(date -d "$year-$month-1 + 1 month - 1 day" +%d)
wday=$(date -d "$year-$month-1" +%w)
for (( day=1; day<=$last; day++ )); do
if (( wday == 1 || wday == 4 )); then
printf "%4d-%02d-%02d\n" $year $month $day
fi
(( wday = (wday + 1) % 7 ))
done
2013-02-04
2013-02-07
2013-02-11
2013-02-14
2013-02-18
2013-02-21
2013-02-25
2013-02-28
year=2013
month=02
#Monday=1,Sunday=7
display_days="1 4"
for day in $(seq 1 31)
do
dow=$(date -d "$year-$month-$day" +%u 2>/dev/null)
for d in $display_days
do
if [ -z $dow ]; then continue; fi
if [ "$dow" -eq "$d" ]
then
date -d "$year-$month-$day" +%y-%m-%d
fi
done
done
Or just defer to ncal.
LC_ALL=C ncal "$#" | sed -n 's/\(Mo\|Th\)//p'
Weekdays are subject to localization so I added a C locale just in case.
Another way:
year=2013 month=02
cal $month $year |
sed '1,2d; s/^.. \(..\) .. .. \(..\).*/\1\n\2/' |
sed "/^ *$/d; s/^ /0/; s/^/$year-$month-/"

bash shell script for yesterdays date (last working day)

I am writing a bash script that needs to print the date of the last working day. So for example if the script is run on a Monday, it will print the date for last Friday.
I found that this prints yesterdays date:
date -d '1 day ago' +'%Y/%m/%d'
I also know that I can get the day of the week by using this statement
date +%w
I want to combine these two statements in order to have a little helper script that prints the required date. The logic goes something like this (note: its Pseudo code - I've never written a bash script)
DAY_OF_WEEK = `date +%w`
if (%DAY_OF_WEEK == 1)
LOOK_BACK = 3
elif
LOOK_BACK = 1
fi
echo `date -d '%LOOK_BACK day ago' +'%Y/%m/%d'`
Can someone help by correcting the pseudo code above?
(I am running on Ubuntu 10.0.4)
You were so close:
day_or_week=`date +%w`
if [ $day_or_week == 1 ] ; then
look_back=3
else
look_back=1
fi
date -d "$look_back day ago" +'%Y/%m/%d'
Sunday also needs to be checked.
DAY_OF_WEEK=`date +%w`
if [ $DAY_OF_WEEK = 0 ] ; then
LOOK_BACK=2
elif [ $DAY_OF_WEEK = 1 ] ; then
LOOK_BACK=3
else
LOOK_BACK=1
fi
date -d "$LOOK_BACK day ago" +'%Y/%m/%d'
I'm using a Mac, so my date command doesn't have the same -d flag yours seems to, but the following should work if it behaves as you've indicated:
if [[ $(date +%w) == 1 ]]
then
LOOK_BACK=3
else
LOOK_BACK=1
fi
date -d "${LOOK_BACK} day ago" +%Y/%m/%d
For OSX (tested on 10.9.2 and 10.13.4), so probably any environment where you are using BSD date.
if [ $(date +%w) == 1 ] ; then
date -v-3d +'%Y/%m/%d'
else
date -v-1d +'%Y/%m/%d'
fi
You can check to see if you are using BSD date by
$ man date | grep "BSD General"
Putting the other answers together, I came up with this:
last_workday() {
from_date="${#:-today}"
day_of_week=$(date +%w --date="${from_date}")
if [ ${day_of_week} = "0" ] ; then
look_back=2
elif [ ${day_of_week} = "1" ] ; then
look_back=3
else
look_back=1
fi
date -d "${from_date} - ${look_back} day" +'%Y/%m/%d'
}
next_workday() {
from_date="${#:-today}"
day_of_week=$(date +%w --date="${from_date}")
if [ ${day_of_week} = "5" ] ; then
look_forward=3
elif [ ${day_of_week} = "6" ] ; then
look_forward=2
else
look_back=1
fi
date -d "${from_date} + ${look_forward} day" +'%Y/%m/%d'
}
for i in $(seq 16); do
now=$(date +'%Y/%m/%d' --date="today + ${i} day")
prev=$(last_workday "${now}")
next=$(next_workday "${now}")
echo "${now}: ${prev} ${next}"
done
A more concise form using a bash inline "ternary" expression:
[[ $(date +%w) == 1 ]] && days=3 || days=1
date -d "$days day ago" +"%Y-%m-%d"

Check to see if today is a certain date

I want to check if the day is Sunday, but for some reason I can't get it to work.
[[ "date '+%a'" == "Sun" ]] && echo "Today is Sunday"
Use $(...) to execute a command and return the output as a string:
[[ $(date '+%a') == "Sun" ]]
You can use the date +%u to get the day number of the week... 1 - 7 with Monday being 1 that way you should not have an issue with non-english locales
[[ $(date '+%a') == "Sun" ]] && echo "Sunday!"
case "$(date '+%a')" in "Sun" ) echo "sunday";; esac
For completion:
If you have multiple locales I advise to use +%u cf. man date:
%u day of week (1..7); 1 is Monday
Today is monday:
date +%u
1
if [[ $(date +%u) -eq 1 ]]; then
echo 'ho no :c'
fi
ho no :c
hth

Resources