This kills my linter in vs-code.
Is there a one-liner that could better perform this?
echo -n "$((($(date -j -f "%Y%m%d" "$(( $(date +"%Y0101")+10000 ))" "+%s") - $(date "+%s"))/(60*60*24)))";
echo " days until $(( $(date +"%Y")+1 ))"
prints:
308 days until 2020
I would use python:
python -c 'from datetime import datetime as dt;y=dt.now().year+1;print('{} days until {}'.format((dt(y,1,1)-dt.now()).days,y))'
which is the one-linerized version of:
from datetime import datetime as dt
next_year = dt.now().year + 1;
days = (dt(next_year, 1, 1) - dt.now()).days
print('{} days until {}'.format(days, next_year))
Output (using the UTC timezone):
306 days until 2020
Pure Bash one-liner (tested on Linux, no Mac here)
eoy=$([ -n "$(date -d 'Feb 29' '+%-j' 2>/dev/null)" ] && echo 366); echo "$((${eoy:-365} - $(date '+%-j'))) days until $(($(date -d 'Dec 31' '+%Y') +1))"
Result:
307 days until 2020
Testing a leap year:
eoy=$([ -z "$(date -d 'Feb 29 2020' '+%-j' 2>/dev/null)" ] && echo 366); echo "$((${eoy:-365} - $(date '+%-j'))) days until $(($(date -d 'Dec 31 2020' '+%Y') +1))"
Result:
308 days until 2021
Same in 2 lines:
# year days if leap year
eoy=$([ -z "$(date -d 'Feb 29' '+%-j' 2>/dev/null)" ] && echo 366)
# ${eoy:-365} -> if $eoy is not set or empty string use default 365
echo "$((${eoy:-365} - $(date '+%-j'))) days until $(($(date -d 'Dec 31' '+%Y') +1))"
Related
Let's say I have a date in this format: 2021-01-26
How would I check to see if this date is 60 days old?
Something like this?
if ($date -gt 60)
then
echo "Date is older than 60 days"
fi
Use the date command to create the date 60 days ago, and compare with that.
sixty_days_ago=$(date +%F -d '60 days ago')
if [[ $date < $sixty_days_ago ]]
then echo "Date is older than 60 days"
fi
#!/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
I am trying to test a date ...if it's between those 2 time frames i want to print them...
But i get errors..This is my script
today_time=$(date +%H:%M:%S --date '-1 sec')
today_dow=$(date +"%u")
today_less=$(date +%H:%M:%S --date '-1 min')
today_more=$(date +%H:%M:%S --date '+1 min')
echo $today_less
echo $today_time
echo $today_more
if [ $today_less -gt $today_time ] && [ $today_time -lt $today_more ]; then
echo "$today_less"
echo "$today_time"
echo "$today_more"
else
echo no
fi
I have tried -ge with -le and gives me: Integer expression expected
-gt and -lt: Integer expression expected
I also used '<' and '>' and gives me: No such file or directory.
I need to make this work with time dates only...not with int
Cause the time i will extract it from the db and replace today_time with the time from db.
Your output is not the digits, but strings like:
[sahaquiel#sahaquiel-PC ~]$ date +%H:%M:%S --date '-1 min'
13:40:30
Convert it to Unixtime and compare clear numbers, for example:
today_time=$(date +%H:%M:%S --date '-1 sec')
today_time_u=$(date +%s --date '-1 sec')
today_dow=$(date +"%u")
today_less=$(date +%H:%M:%S --date '-1 min')
today_less_u=$(date +%s --date '-1 min')
today_more=$(date +%H:%M:%S --date '+1 min')
today_more_u=$(date +%s --date '+1 min')
echo $today_less
echo $today_time
echo $today_more
if [ $today_less_u -gt $today_time_u -a $today_time_u -lt $today_more_u ]; then
echo "$today_less"
echo "$today_time"
echo "$today_more"
else
echo no
fi
And once more, in your example, $today_less is current date - 1 minute; $today_time is current date - 1 second; So, $today_time > $today_less every time and your if [ $today_less_u -gt $today_time_u part will be false every time, so you will not be able get anything but echo no in else statement.
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-/"
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"