给定月份/年份的最后一个星期六



在Unix中,我想找到给定月份和年份的最后一个星期六的日期(月中的某天)。我知道cal会给我给定月份/一年的日历。获得最后一个星期六的好方法是什么?

更新:我想要一个可以用来应用于一周中任何一天的解决方案。例如,我也可以使用相同的方法来查找最后一个星期日或星期三的日期。

为此使用 awk。考虑一下:

cal 5 2013 | awk 'NF>6{a=$7} END{print a}'

输出:

25

如果您不想只通过管道/解析cal输出,则可以使用算法来确定日期的工作日,然后获取 12 月 31 日的工作日,并向后移动使其成为星期六所需的天数。

但是解析 cal 可能更简单。

我对这个问题还有另一个答案,它有点冗长的 Bash 脚本,效率不高,但很容易理解。基本思想是循环给定月份和年份的 22 到 31 天,并按 date +'%u' 检查这些日子中每一天的星期几。返回所需工作日的最后一天(例如星期六)存储在变量RESULT_DAY中,该变量将包含循环后的结果。

#!/bin/bash
DAY_OF_WEEK=6 # 1=Monday, ..., 7=Sunday
THE_YEAR=2016
THE_MONTH=10

RESULT_DAY=0
YEAR_MONTH_STR=${THE_YEAR}"-"${THE_MONTH}  # Example value: "2016-10"
for DAYNO in 22 23 24 25 26 27 28 29 30 31
do
  DATE_TO_CHECK=${YEAR_MONTH_STR}"-"${DAYNO}
  DATE_RESULT=$(date --date=$DATE_TO_CHECK '+%u')
  if [ $? -eq 0 ]
  then
    if [ $DATE_RESULT -eq $DAY_OF_WEEK ]
    then
      RESULT_DAY=$DAYNO
    fi
  fi
done
RESULT_DATE_COMPLETE=${YEAR_MONTH_STR}"-"${RESULT_DAY}
echo -e "nResult date (YYYY-MM-DD): "$(date --date=$RESULT_DATE_COMPLETE +'%Y-%m-%d (%A)')

我们通过检查$?的值"0"来检查date的结果代码,因此我们可以忽略非法日期(例如不存在的 2 月 31 日)。

一个月的第 22 天是我们必须考虑的最早日期,因为在最短的月份(非闰年的二月)中,这是最后一次出现的最早日期,例如星期六。