一个月/一年的最后一个星期六

时间:2022-08-08 09:22:26

In Unix, I want to find the date (day of month) of the last Saturday of a given month and year. I know cal will give me the calendar for a given month / year. What is a good way to get the last Saturday?

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

Update: I'd like a solution that I could use to apply to any day of the week. For example, I could use the same method to find the date of the last Sunday or Wednesday as well.

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

3 个解决方案

#1


3  

Use awk for that. Consider this:

使用awk。考虑一下:

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

OUTPUT:

25

#2


0  

If you didn't want to just pipe/parse cal output, you could use an algorithm to determine the weekday of a date, then get the weekday for December 31st and move backward the number of days needed to make it a Saturday.

如果您不希望只使用管道/解析cal输出,您可以使用一个算法来确定日期的工作日,然后获取12月31日的工作日,并将周六所需的天数向后移动。

But parsing cal is probably simpler.

但是解析cal可能更简单。

#3


0  

I have another answer for this question, which is a bit lengthy Bash script and not so efficient, but easy to understand. The basic idea is it to loop over the days 22 till 31 for the given month and year and check the day of the week for each of these days by date +'%u'. The last day for which this returns the wanted week day (e.g. Saturday) is stored in the variable RESULT_DAY, which will contain the result after the loop.

对于这个问题,我有另一个答案,这是一个有点冗长的Bash脚本,效率不高,但是很容易理解。它的基本思想是对给定月份和年份的22天到31天进行循环,并按日期+'%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)')

We check for date's result code by checking $? for value "0", so we can ignore illegal days (e.g. 31st of February, which does not exist).

我们通过检查$来检查日期的结果代码?对于价值“0”,我们可以忽略非法的日子(例如2月31日,不存在)。

The 22nd day of a month is the earliest date we have to consider, because in the shortest month (February in non-leap years) this is the earliest day for the last occurrence of a e.g. Saturday.

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

#1


3  

Use awk for that. Consider this:

使用awk。考虑一下:

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

OUTPUT:

25

#2


0  

If you didn't want to just pipe/parse cal output, you could use an algorithm to determine the weekday of a date, then get the weekday for December 31st and move backward the number of days needed to make it a Saturday.

如果您不希望只使用管道/解析cal输出,您可以使用一个算法来确定日期的工作日,然后获取12月31日的工作日,并将周六所需的天数向后移动。

But parsing cal is probably simpler.

但是解析cal可能更简单。

#3


0  

I have another answer for this question, which is a bit lengthy Bash script and not so efficient, but easy to understand. The basic idea is it to loop over the days 22 till 31 for the given month and year and check the day of the week for each of these days by date +'%u'. The last day for which this returns the wanted week day (e.g. Saturday) is stored in the variable RESULT_DAY, which will contain the result after the loop.

对于这个问题,我有另一个答案,这是一个有点冗长的Bash脚本,效率不高,但是很容易理解。它的基本思想是对给定月份和年份的22天到31天进行循环,并按日期+'%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)')

We check for date's result code by checking $? for value "0", so we can ignore illegal days (e.g. 31st of February, which does not exist).

我们通过检查$来检查日期的结果代码?对于价值“0”,我们可以忽略非法的日子(例如2月31日,不存在)。

The 22nd day of a month is the earliest date we have to consider, because in the shortest month (February in non-leap years) this is the earliest day for the last occurrence of a e.g. Saturday.

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