2016-04-21 82 views
0

问:如何获取最新日期为given_day_of_the_week如何获取Bash中某个特定日期的最新日期

例子:例如,如果今天是2016年4月21日,我只想得到一个given_day_of_the_week例如Monday这将是2016-04-18的日期。如果代码明天运行,直到下一个given_day_of_the_week前一天,此日期仍将返回。

说明:代码应返回最新given_day_of_the_week的(Monday)日起至周日2016年4月24日,然后代码运行的同位将在2016-04-25下周返回。

+0

击不包括日期操作功能。你可以使用系统的'date'命令来做你想做的事情,但是这个命令的使用因操作系统而异,而且你没有提到你使用的是什么操作系统。另外...你有什么尝试?我们大多数人都很乐意帮助你改进自己的技艺,但不愿意担任短期无偿编程人员。在[MCVE](http://stackoverflow.com/help/mcve)中向我们展示您的工作,您期待的结果以及您获得的结果,我们将帮助您弄清楚。 – ghoti

回答

1

需要GNU日期:

today_dow=$(date +%w) 
days=(Sunday Monday Tuesday Wednesday Thursday Friday Saturday) 
for ((dow=0; dow<7; dow++)); do 
    if ((dow < today_dow)); then 
     date -d "last ${days[dow]}" 
    else 
     date -d "${days[dow]}" 
    fi 
done 
Sun Apr 17 00:00:00 EDT 2016 
Mon Apr 18 00:00:00 EDT 2016 
Tue Apr 19 00:00:00 EDT 2016 
Wed Apr 20 00:00:00 EDT 2016 
Thu Apr 21 00:00:00 EDT 2016 
Fri Apr 22 00:00:00 EDT 2016 
Sat Apr 23 00:00:00 EDT 2016 

因此,我们可以这样做:

given_day_of_the_week() { 
    local days=(Sunday Monday Tuesday Wednesday Thursday Friday Saturday) 
    local today_dow=$(date +%w) 
    local dow datestr 
    for ((dow=0; dow<7; dow++)); do 
     if [[ "${days[dow],,}" == "${1,,}" ]]; then 
      if ((dow < today_dow)); then 
       datestr="last ${days[dow]}" 
      else 
       datestr="${days[dow]}" 
      fi 
      date -d "$datestr" "+%F" 
     fi 
    done 
} 

结果造成:

$ given_day_of_the_week tuesday 
2016-04-19 
$ given_day_of_the_week friday 
2016-04-22 

硬编码在工作日的名称一样,会给你的问题如果你在不同的场所


回应@ ryenus的评论:

$ given_day_of_the_week() { 
    local -A days=([sunday]=0 [monday]=1 [tuesday]=2 [wednesday]=3 [thursday]=4 [friday]=5 [saturday]=6) 
    local today_dow=$(date +%w) 
    local datestr=${1,,} 
    local dow=${days[$datestr]} 
    [[ -z "$dow" ]] && { echo "error: unknown day: '$1'" >&2; return 1; } 
    ((dow < today_dow)) && datestr="last $datestr" 
    date -d "$datestr" "+%F" 
} 
$ given_day_of_the_week friday 
2016-04-22 
$ given_day_of_the_week monday 
2016-04-18 
$ given_day_of_the_week FOO 
error: unknown day: 'FOO' 
+0

Upvoted!因为你聪明地使用了'date -d'和'date -d last ...'。 – ryenus

+0

您可能会考虑直接比较day_of_week,而不循环,以决定是否添加最后一个前缀:'[$(date -d monday +%w)-lt $(date +%w)] && date_str_prefix =“last” ' – ryenus

0

通过@格伦 - 杰克曼的回答启发,但更简单:

given_day_of_the_week=$1 
f='%A %Y-%m-%d' 
tomorrow=`date -d 'tomorrow' +"$f"` 
today=`date -d 'today' +"$f"` 
last5=`seq 1 5 | xargs -I{} date -d '{} day ago' +"$f"` 
echo -e "$tomorrow\n$today\n$last5" | 
    grep -i $given_day_of_the_week | 
    cut -d' ' -f2 

注:这个答案确实能给如果用明天的周一日期在星期天。如果在星期一使用,它还会显示星期二的明天日期。不是100%确定,如果这是你的想法。

相反,如果这个想法是要始终与当前星期天去 - 周六,这将做到这一点:

given_day_of_the_week=$1 
f='%A %Y-%m-%d' 

[ `date +%A` = 'Sunday' ] && first=`date -d 'today' +"$f"` || 
    first=`date -d 'last Sunday' +"$f"` 

rest=`seq 1 6 | xargs -I{} date -d "$first +{} day" +"$f"` 

echo -e "$first\n$rest" | 
    grep -i $given_day_of_the_week | 
    cut -d' ' -f2 
0
# requires bash 4.x and GNU date 
last_kday() { 
    local kday=$1 
    local -A numbers=([sunday]=0 [monday]=1 [tuesday]=2 [wednesday]=3 
        [thursday]=4 [friday]=5 [saturday]=6) 
    if [[ $kday == *day ]]; then 
    kday=${numbers[${kday,,}]} 
    elif [[ $kday != [0-6] ]]; then 
    echo >&2 "Usage: last_kday weekday" 
    return 1 
    fi 

    local today=$(date +%w) 
    local days_ago=$((today - kday)) 
    if ((days_ago < 0)); then let days_ago+=7; fi 
    date -d "$days_ago days ago" +%F 
}