Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to get the dates of all mondays in a year

I need to sort data on a weekly base and all i have are dates in a logfile. Therefore to sort out data per week i would like to create a list with the dates of all mondays for a given year. I have tried to work something out and the only idea i currently have is to use ncal with year and month as argument looping over all months and extracting all mondays. Isn't there a more efficient way?

like image 462
Hjelm Avatar asked Feb 18 '11 07:02

Hjelm


2 Answers

To get all mondays, by getting all dates and filtering by Mondays:

for i in `seq 0 365`
    do date -d "+$i day"
done | grep Mon

Of course, you could also take a monday and keep incrementing by 7 days.

like image 91
Sjoerd Avatar answered Sep 19 '22 05:09

Sjoerd


hope that's what you mean. Below can be changed to vary the output formats of the dates.

date command can be used for that, dunno if ncal is any more/less efficient.

I know you went for "binning" now, but here is a more readable v.

$ cat /tmp/1.sh
#!/bin/bash

test -z "$year" && {
    echo "I expect you to set \$year environment variable"
    echo "In return I will display you the Mondays of this year"
    exit 1
}

# change me if you would like the date format to be different
# man date would tell you all the combinations you can use here
DATE_FORMAT="+%Y-%m-%d"

# change me if you change the date format above. I need to be
# able to extract the year from the date I'm shoing you
GET_YEAR="s/-.*//"

# this value is a week, in milliseconds. Changing it would change
# what I'm doing.
WEEK_INC=604800

# Use another 3-digit week day name here, to see dates for other week days
DAY_OF_WEEK=Mon

# stage 1, let's find us the first day of the week in this year

d=1
# is it DAY_OF_WEEK yet?
while test "$(date -d ${year}-1-${d} +%a)" != "$DAY_OF_WEEK"; do
# no, so let's look at the next day
    d=$((d+1));
done;

# let's ask for the milliseconds for that DAY_OF_WEEK that I found above
umon=$(date -d ${year}-1-${d} +%s)

# let's loop until we break from inside
while true; do
   # ndate is the date that we testing right now
   ndate=$(date -d @$umon "$DATE_FORMAT");
   # let's extract year
   ny=$(echo $ndate|sed "$GET_YEAR");
   # did we go over this year? If yes, then break out
   test $ny -ne $year && { break; }
   # move on to next week
   umon=$((umon+WEEK_INC))
   # display the date so far
   echo "$ndate"
done
like image 41
Pawel Veselov Avatar answered Sep 22 '22 05:09

Pawel Veselov