I need to get the list of all Saturdays in a given date range ex: 20170101 to 20170630 in YYYYMMDD format in linux
Asked
Active
Viewed 291 times
-1
-
1Do any of the current answers solve your problem? If so, please indicate one by clicking the checkmark next to it. Thank you! – Jeff Schaller Jul 01 '17 at 21:03
4 Answers
3
Using GNU date and brute force:
start=20170101
end=20170630
cur=$start
increment="1 day"
while [ $(date +%s -d "$cur") -le $(date +%s -d "$end") ]
do
if [ "$(date +%A -d "$cur")" = "Saturday" ]
then
printf "%s\n" "$cur"
increment="1 week"
fi
cur=$(date +%Y%m%d -d "$cur + $increment")
done
Jeff Schaller
- 66,199
- 35
- 114
- 250
-
I think *Linux Journal* had an article similar to this question, but they used the `cal` program. I can't find it now, of course. – KevinO Jun 19 '17 at 15:35
-
Maybe it was [this one](http://www.linuxjournal.com/content/calculating-day-week-finally)? Just beware if `cal` underlines today: https://unix.stackexchange.com/q/346153/117549 – Jeff Schaller Jun 20 '17 at 12:06
1
Make a script with this:
#! /bin/bash
cur=20170101
end=20170630
# First upcoming saturday is:
cur=$(( cur+(6-$( date -d $cur +%w )) ))
# Keep increment by 7 days until 'end'
while (( end>cur )); do
echo $cur
cur=$( date -d "$cur+7days" +%Y%m%d )
done
It will give:
$ ./ILoveSaturdays.bash
20170107
20170114
...
20170617
20170624
Jeff Schaller
- 66,199
- 35
- 114
- 250
hschou
- 2,845
- 12
- 15
-
You beat me to it! The offset from date +%W is wrong if the start date is a Saturday, though. – tripleee Jun 19 '17 at 17:55
-
@tripleee If you start on a Saturday, %w would be 6, and 6-6 = 0. I guess it should work. – hschou Jun 19 '17 at 18:03
1
With GNU date, trying to run as few date commands as possible (2):
TZ=UTC0 date -f - '+%s %w' << EOF |
20170101
20170630
EOF
awk -v d=86400 '{
d1 = $1 + (6 - $2) * d
getline
for (t = d1; t <= $1; t += 7 * d) print "@" t}' |
TZ=UTC0 date -f - +%Y%m%d
Stéphane Chazelas
- 522,931
- 91
- 1,010
- 1,501
0
Let's do this in perl :
perl -e '
use POSIX "strftime";
$start=$ARGV[0];
$end=$ARGV[1];
if(! ($start =~ /^(\d\d\d\d)(\d\d)(\d\d)$/)){
die "bad format for first arg";
}
$epoch=(($1-1970)*365+($2-1)*28+$3-1)*24*60*60;
if(! ($end =~ /^(\d\d\d\d)(\d\d)(\d\d)$/)){
die "bad format for first arg";
}
while(1){
$cur=strftime("%Y%m%d", gmtime $epoch);
if($cur ge $start){last;};
$epoch += 24*60*60;
}
while(1){
$wd = strftime("%u", gmtime $epoch);
$cur = strftime("%Y%m%d", gmtime $epoch);
if($cur >= $end){last;}
if($wd == 6){
printf "$cur\n";
}
$epoch += 24*60*60;
}' 20170101 20170630
Vouze
- 829
- 5
- 8