给定两个数字,月份和年份,我如何计算该月的第一天和最后一天?我的目标是输出这三行:
月/年(文本形式的月,但这是微不足道的)
对于一个月中的每一天:当天的星期几的名称:星期五。& 周六 & 太阳。[...]
月内的天数:1 & 2 & 3 [...] & 28 & .. ?
我正在寻找使用 GNUdate
或 BSD date
(在 OS X 上)的解决方案。
小智 14
# Last month:
l_first_date=$(date -d "`date +%Y%m01` -1 month" +%Y-%m-%d)
l_last_date=$(date -d "`date +%Y%m01` -1 day" +%Y-%m-%d)
# This month:
t_first_date=$(date -d "`date +%Y%m01`" +%Y-%m-%d)
t_last_date=$(date -d "`date +%Y%m01` +1 month -1 day" +%Y-%m-%d)
# Next month:
n_first_date=$(date -d "`date +%Y%m01` +1 month" +%Y-%m-%d)
n_last_date=$(date -d "`date +%Y%m01` +2 month -1 day" +%Y-%m-%d)
# Print everything
echo "Last month: $l_first_date to $l_last_date"
echo "This month: $t_first_date to $t_last_date"
echo "Next month: $n_first_date to $n_last_date"
Run Code Online (Sandbox Code Playgroud)
我会说实话;从你问这个问题的方式我感觉到你被分配了一些作业,所以我会在答案中留下几个步骤作为读者的练习:
您需要仔细查看date
手册页;尤其是-d
标志,它允许您检查任何一天。Y 年 M 月的第一天将是“M/01/Y”
获得当月的最后一天,最好的办法是在给定的月份数上加 1,然后在日期中减去一天。
提示:date
实际上可以接受一些广泛的算术;例如,我可以说date -d "01/07/2012 + 1 month - 1 day"
,它会给我正确的答案。
您可以通过研究手册页的“格式”部分来了解如何在 2) 和 3) 中显示所需的输出date
。
提示:查看%a
和%d
前段时间我有类似的问题。有我的解决方案:
$ ./get_dates.sh 2012 07
The first day is 01.2012.07, Sunday
The last day is 31.2012.07, Tuesday
$ cal
July 2012
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Run Code Online (Sandbox Code Playgroud)
脚本本身:
#!/bin/bash
# last day for month
lastday() {
# ja fe ma ap ma jn jl ag se oc no de
mlength=('xx' '31' '28' '31' '30' '31' '30' '31' '31' '30' '31' '30' '31')
year=$1
month=$2
if [ $month -ne 2 ] ; then
echo ${mlength[$month]}
return 0
fi
leap=0
((!(year%100))) && { ((!(year%400))) && leap=1 ; } || { ((!(year%4))) && leap=1 ; }
feblength=28
((leap)) && feblength=29
echo $feblength
}
# date to Julian date
date2jd() {
year=$1
month=$2
day=$3
lday=$(lastday $year $month) || exit $?
if ((day<1 || day> lday)) ; then
echo day out of range
exit 1
fi
echo $(( jd = day - 32075
+ 1461 * (year + 4800 - (14 - month)/12)/4
+ 367 * (month - 2 + (14 - month)/12*12)/12
- 3 * ((year + 4900 - (14 - month)/12)/100)/4
- 2400001 ))
}
jd2dow()
{
days=('Sunday' 'Monday' 'Tuesday' 'Wednesday' 'Thursday' 'Friday' 'Saturday')
jd=$1
if ((jd<1 || jd>782028)) ; then
echo julian day out of range
return 1
fi
((dow=(jd+3)%7))
echo ${days[dow]}
}
echo -n "The first day is 01.$1.$2, "
jd2dow $(date2jd $1 $2 01)
echo -n "The last day is $(lastday $1 $2).$1.$2, "
jd2dow $(date2jd $1 $2 $(lastday $1 $2))
Run Code Online (Sandbox Code Playgroud)
我date
在需要它的机器上没有 GNU ,因此我没有用 date 解决它。可能有更漂亮的解决方案。