查找一个月的第三个星期日之前的星期一

时间:2015-06-24 08:57:19

标签: bash shell date

如何在该月的第三个星期日之前生成一个"周一列表"在shell脚本中接下来的N个月?

date会识别相当广泛的操作集(例如today + 3 months),但我找不到符合我需求的任何内容。

任何使用常见GNU和BSD命令的东西都可以。特定于bash的答案也可以。

3 个答案:

答案 0 :(得分:1)

使用GNU date

$ cat mon-before-3rd-sun.sh
mon_before_3rd_sun()
{
    local year=$1
    local mon=$2
    local seconds weekday

    # get the 1st day of the month
    seconds=$(date +%s -d $year-$mon-1)

    # weekday of the 1st day of the month
    weekday=$(date +%u -d @$seconds)

    # 1st Sunday of the month
    ((seconds += (7 - weekday) * 86400))

    # Monday before 3rd Sunday (i.e. after 2nd Sunday)
    ((seconds += 8 * 86400))
    date '+%Y-%m-%d' -d @$seconds
}

for ((mon = 1; mon <= 12; ++mon)); do
    mon_before_3rd_sun 2015 $mon
done
$ bash mon-before-3rd-sun.sh
2015-01-12
2015-02-09
2015-03-09
2015-04-13
2015-05-11
2015-06-15
2015-07-13
2015-08-10
2015-09-14
2015-10-12
2015-11-09
2015-12-14
$

答案 1 :(得分:1)

它只是一个月第一天的16 - '%u'

expr `date -d"$year-$month-1" +'16 - %u'`

%u day of week (1..7); 1 is Monday

答案 2 :(得分:1)

这个怎么样(为长变量名称道歉,虽然这更多是关于指令而不是效率)

#!/bin/bash

function getMonBefore3rdSunInMonth
{
    # Get the date N months from today.
    monthN=$( date --date="+ ${1} month" +"%m/%d/%Y" )
    # The number of days from that date to the first of the month.
    daysSinceFirstofMonth=$(( $( date --date="${monthN}" +"%d" ) - 1 ))
    # The week-day of first of that month (0..6); 0 is Sunday
    weekDayFirstOfMonth=$( date --date="${monthN}- ${daysSinceFirstofMonth} days" +"%w" )
    # The number of days between the given date and the Monday before
    # the third Wednesday of the month (start at the begining of the month
    # add an offset to the first Sunday, add 14 days to get to third and
    # take off 6 days to get back to previous Monday.
    offsetToMonBefore3rdSunInMonth=$(( -${daysSinceFirstofMonth} + ( ( 7 - ${weekDayFirstOfMonth} ) % 7 ) + 14 - 6 ))
    # Use the offset to work out the date.
    monBefore3rdSunInMonth=$( date --date="${monthN} + ${offsetToMonBefore3rdSunInMonth} days" +"%m/%d/%Y" )
    echo ${monBefore3rdSunInMonth}
}

N=${1}
for n in $( seq ${N} )
do
    getMonBefore3rdSunInMonth $n
done

$ ./getMonBefore3rdSunInMonth.sh 12
07/13/2015
08/10/2015
09/14/2015
10/12/2015
11/09/2015
12/14/2015
01/11/2016
02/15/2016
03/14/2016
04/11/2016
05/09/2016
06/13/2016