如何使用bash来获取当前年度的每个月的最后一天而不使用if else或switch或while循环?

Jac*_*ack 12 unix bash

我们知道每个月每个月的最大日期如下:

Jan - 31 days
Feb - 28 days / 29 days (leap year)
Mar - 31 days
Apr - 30 days
May - 31 days
Jun - 30 days
Jul - 31 days
Aug - 31 days
Sep - 30 days
Oct - 31 days
Nov - 30 days
Dec - 31 days
Run Code Online (Sandbox Code Playgroud)

如何让bash在不使用if elseor switchwhile循环的情况下返回当前年份的值(每个月的最后一天)?

gle*_*man 37

我的看法:

for m in {1..12}; do
  date -d "$m/1 + 1 month - 1 day" "+%b - %d days"; 
done
Run Code Online (Sandbox Code Playgroud)

解释:对于第一次迭代,当m = 1时,-d参数为"1/1 + 1个月 - 1天","1/1"被解释为1月1日.所以1月1日+ 1个月 - 1天是1月31日.下一次迭代"2/1"是2月1日,加上一个月减去一天到2月28日或29日.依此类推.

  • 啊,是的,领悟:我一开始以为$m/1是除法,但其实是计算的基准日。我添加了年份,所以它更灵活,可能不那么令人困惑:`y=2000; 米=2;日期 --date="$y/$m/1 + 1 个月 - 1 天" "+%b %Y - %d 天";` (2认同)
  • 与这里的其他几个答案一样,这需要 GNU“date”,它通常不是安装在非 Linux 系统上的版本。 (2认同)

cly*_*ish 11

cat <<EOF
Jan - 31 days
Feb - `date -d "yesterday 3/1" +"%d"` days
Mar - 31 days
Apr - 30 days
May - 31 days
Jun - 30 days
Jul - 31 days
Aug - 31 days
Sep - 30 days
Oct - 31 days
Nov - 30 days
Dec - 31 days
EOF
Run Code Online (Sandbox Code Playgroud)

  • 我想同时对你投赞成票和反对票;) *(我决定投赞成票)* (2认同)

amd*_*mdn 5

假设您允许“ for”,则以下内容以bash表示

for m in {1..12}; do
    echo $(date -d $m/1/1 +%b) - $(date -d "$(($m%12+1))/1 - 1 days" +%d) days
done
Run Code Online (Sandbox Code Playgroud)

产生这个

 Jan - 31 days
 Feb - 29 days
 Mar - 31 days
 Apr - 30 days
 May - 31 days
 Jun - 30 days
 Jul - 31 days
 Aug - 31 days
 Sep - 30 days
 Oct - 31 days
 Nov - 30 days
 Dec - 31 days
Run Code Online (Sandbox Code Playgroud)

注意:我删除了 cal

对于那些喜欢琐事的人:

Number months from 1 to 12 and look at the binary representation in four
bits {b3,b2,b1,b0}.  A month has 31 days if and only if b3 differs from b0.
All other months have 30 days except for February.
Run Code Online (Sandbox Code Playgroud)

因此,除了二月,这是可行的:

for m in {1..12}; do
    echo $(date -d $m/1/1 +%b) - $((30+($m>>3^$m&1))) days
done
Run Code Online (Sandbox Code Playgroud)

结果:

Jan - 31 days
Feb - 30 days (wrong)
Mar - 31 days
Apr - 30 days
May - 31 days
Jun - 30 days
Jul - 31 days
Aug - 31 days
Sep - 30 days
Oct - 31 days
Nov - 30 days
Dec - 31 days
Run Code Online (Sandbox Code Playgroud)


Jos*_*itt 5

使用 if 语句或分叉为二进制文件,返回补偿闰年二月变化的月份天数,无需循环。

此代码测试日期以查看所请求年份的 2 月 29 日是否有效,如果有效,则更新日期偏移字符串中的第二个字符。月份参数选择相应的子字符串并将月份差异添加到 28。

function daysin()
{
   s=303232332323                                        # normal year
   ((!($2%4)&&($2%100||!($2%400)))) && s=313232332323      # leap year
   echo $[ ${s:$[$1-1]:1} + 28 ]
}

daysin $1 $2                                               #daysin [1-12] [YYYY]
Run Code Online (Sandbox Code Playgroud)


小智 5

cal $(date +"%m %Y") | awk 'NF {DAYS = $NF}; END {print DAYS}'
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码片段可以解决问题,但[包括解释](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而那些人可能不知道您建议代码的原因。 (2认同)